igniteui-webcomponents 7.3.2 → 7.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -0
- package/animations/easings.d.ts +21 -31
- package/animations/easings.js +21 -34
- package/animations/easings.js.map +1 -1
- package/animations/player.d.ts +8 -16
- package/animations/player.js +5 -8
- package/animations/player.js.map +1 -1
- package/animations/view-transition.d.ts +10 -10
- package/animations/view-transition.js +26 -37
- package/animations/view-transition.js.map +1 -1
- package/components/breadcrumb/breadcrumb.d.ts +74 -0
- package/components/breadcrumb/breadcrumb.js +107 -0
- package/components/breadcrumb/breadcrumb.js.map +1 -0
- package/components/breadcrumb/breadcrumbs.d.ts +60 -0
- package/components/breadcrumb/breadcrumbs.js +50 -0
- package/components/breadcrumb/breadcrumbs.js.map +1 -0
- package/components/breadcrumb/themes/breadcrumb.base.css.js +3 -0
- package/components/breadcrumb/themes/breadcrumb.base.css.js.map +1 -0
- package/components/breadcrumb/themes/breadcrumbs.base.css.d.ts +1 -0
- package/components/{resize-container/themes/resize-container.base.css.js → breadcrumb/themes/breadcrumbs.base.css.js} +2 -2
- package/components/breadcrumb/themes/breadcrumbs.base.css.js.map +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.bootstrap.css.d.ts +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.bootstrap.css.js +3 -0
- package/components/breadcrumb/themes/dark/breadcrumb.bootstrap.css.js.map +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.fluent.css.d.ts +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.fluent.css.js +3 -0
- package/components/breadcrumb/themes/dark/breadcrumb.fluent.css.js.map +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.indigo.css.d.ts +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.indigo.css.js +3 -0
- package/components/breadcrumb/themes/dark/breadcrumb.indigo.css.js.map +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.material.css.d.ts +1 -0
- package/components/breadcrumb/themes/dark/breadcrumb.material.css.js +3 -0
- package/components/breadcrumb/themes/dark/breadcrumb.material.css.js.map +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.bootstrap.css.d.ts +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.bootstrap.css.js +3 -0
- package/components/breadcrumb/themes/light/breadcrumb.bootstrap.css.js.map +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.fluent.css.d.ts +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.fluent.css.js +3 -0
- package/components/breadcrumb/themes/light/breadcrumb.fluent.css.js.map +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.indigo.css.d.ts +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.indigo.css.js +3 -0
- package/components/breadcrumb/themes/light/breadcrumb.indigo.css.js.map +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.material.css.d.ts +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.material.css.js +3 -0
- package/components/breadcrumb/themes/light/breadcrumb.material.css.js.map +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.shared.css.d.ts +1 -0
- package/components/breadcrumb/themes/light/breadcrumb.shared.css.js +3 -0
- package/components/breadcrumb/themes/light/breadcrumb.shared.css.js.map +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.bootstrap.css.d.ts +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.bootstrap.css.js +3 -0
- package/components/breadcrumb/themes/shared/breadcrumb.bootstrap.css.js.map +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.common.css.d.ts +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.common.css.js +3 -0
- package/components/breadcrumb/themes/shared/breadcrumb.common.css.js.map +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.fluent.css.d.ts +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.fluent.css.js +3 -0
- package/components/breadcrumb/themes/shared/breadcrumb.fluent.css.js.map +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.indigo.css.d.ts +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.indigo.css.js +3 -0
- package/components/breadcrumb/themes/shared/breadcrumb.indigo.css.js.map +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.material.css.d.ts +1 -0
- package/components/breadcrumb/themes/shared/breadcrumb.material.css.js +3 -0
- package/components/breadcrumb/themes/shared/breadcrumb.material.css.js.map +1 -0
- package/components/breadcrumb/themes/themes.d.ts +2 -0
- package/components/breadcrumb/themes/themes.js +50 -0
- package/components/breadcrumb/themes/themes.js.map +1 -0
- package/components/button/button.d.ts +0 -2
- package/components/button/button.js.map +1 -1
- package/components/button-group/button-group.d.ts +42 -12
- package/components/button-group/button-group.js +82 -34
- package/components/button-group/button-group.js.map +1 -1
- package/components/button-group/toggle-button.d.ts +6 -1
- package/components/button-group/toggle-button.js +28 -2
- package/components/button-group/toggle-button.js.map +1 -1
- package/components/calendar/base.js +2 -1
- package/components/calendar/base.js.map +1 -1
- package/components/calendar/calendar.d.ts +2 -3
- package/components/calendar/calendar.js.map +1 -1
- package/components/calendar/days-view/days-view.d.ts +2 -2
- package/components/calendar/days-view/days-view.js.map +1 -1
- package/components/carousel/carousel-indicator.js +1 -0
- package/components/carousel/carousel-indicator.js.map +1 -1
- package/components/carousel/carousel-slide.d.ts +1 -1
- package/components/carousel/carousel-slide.js.map +1 -1
- package/components/carousel/carousel.d.ts +3 -3
- package/components/carousel/carousel.js.map +1 -1
- package/components/chat/chat-input.d.ts +1 -2
- package/components/chat/chat-input.js +1 -1
- package/components/chat/chat-input.js.map +1 -1
- package/components/chat/chat-state.d.ts +8 -9
- package/components/chat/chat-state.js.map +1 -1
- package/components/chat/chat.d.ts +1 -3
- package/components/chat/chat.js +2 -2
- package/components/chat/chat.js.map +1 -1
- package/components/chat/message-attachments.d.ts +6 -15
- package/components/chat/message-attachments.js.map +1 -1
- package/components/chat/utils.d.ts +0 -1
- package/components/chat/utils.js +1 -1
- package/components/chat/utils.js.map +1 -1
- package/components/checkbox/checkbox-base.d.ts +3 -1
- package/components/checkbox/checkbox-base.js +4 -0
- package/components/checkbox/checkbox-base.js.map +1 -1
- package/components/checkbox/checkbox.js +4 -12
- package/components/checkbox/checkbox.js.map +1 -1
- package/components/checkbox/switch.js +1 -8
- package/components/checkbox/switch.js.map +1 -1
- package/components/chip/chip.d.ts +2 -2
- package/components/chip/chip.js.map +1 -1
- package/components/color-picker/color-picker.d.ts +35 -34
- package/components/color-picker/color-picker.js +12 -7
- package/components/color-picker/color-picker.js.map +1 -1
- package/components/color-picker/common.d.ts +0 -2
- package/components/color-picker/common.js +2 -2
- package/components/color-picker/common.js.map +1 -1
- package/components/color-picker/converters.js.map +1 -1
- package/components/color-picker/picker-canvas.js.map +1 -1
- package/components/combo/combo.d.ts +24 -24
- package/components/combo/combo.js +21 -26
- package/components/combo/combo.js.map +1 -1
- package/components/combo/controllers/data.d.ts +7 -10
- package/components/combo/controllers/data.js.map +1 -1
- package/components/date-picker/date-picker.base.d.ts +22 -27
- package/components/date-picker/date-picker.base.js +9 -3
- package/components/date-picker/date-picker.base.js.map +1 -1
- package/components/date-picker/date-picker.d.ts +1 -1
- package/components/date-picker/date-picker.js +5 -3
- package/components/date-picker/date-picker.js.map +1 -1
- package/components/date-range-picker/date-range-input.d.ts +0 -2
- package/components/date-range-picker/date-range-input.js +0 -6
- package/components/date-range-picker/date-range-input.js.map +1 -1
- package/components/date-range-picker/date-range-picker.d.ts +22 -31
- package/components/date-range-picker/date-range-picker.js +7 -7
- package/components/date-range-picker/date-range-picker.js.map +1 -1
- package/components/date-range-picker/i18n.d.ts +21 -0
- package/components/date-range-picker/i18n.js +10 -0
- package/components/date-range-picker/i18n.js.map +1 -0
- package/components/date-range-picker/predefined-ranges-area.d.ts +3 -3
- package/components/date-range-picker/predefined-ranges-area.js +2 -5
- package/components/date-range-picker/predefined-ranges-area.js.map +1 -1
- package/components/date-range-picker/validators.d.ts +0 -4
- package/components/date-range-picker/validators.js +4 -4
- package/components/date-range-picker/validators.js.map +1 -1
- package/components/date-time-input/date-time-input.base.d.ts +42 -40
- package/components/date-time-input/date-time-input.base.js +9 -5
- package/components/date-time-input/date-time-input.base.js.map +1 -1
- package/components/date-time-input/date-time-input.d.ts +1 -11
- package/components/date-time-input/date-time-input.js +0 -6
- package/components/date-time-input/date-time-input.js.map +1 -1
- package/components/date-time-input/datetime-mask-parser.d.ts +0 -10
- package/components/date-time-input/datetime-mask-parser.js +1 -1
- package/components/date-time-input/datetime-mask-parser.js.map +1 -1
- package/components/dialog/dialog.js.map +1 -1
- package/components/dropdown/dropdown-group.d.ts +2 -10
- package/components/dropdown/dropdown-group.js +2 -27
- package/components/dropdown/dropdown-group.js.map +1 -1
- package/components/dropdown/dropdown.d.ts +17 -23
- package/components/dropdown/dropdown.js +5 -17
- package/components/dropdown/dropdown.js.map +1 -1
- package/components/file-input/file-input.d.ts +7 -2
- package/components/file-input/file-input.js +4 -0
- package/components/file-input/file-input.js.map +1 -1
- package/components/icon/icon.d.ts +1 -1
- package/components/icon/icon.registry.d.ts +6 -6
- package/components/icon/icon.registry.js.map +1 -1
- package/components/input/input-base.d.ts +2 -2
- package/components/input/input-base.js +3 -5
- package/components/input/input-base.js.map +1 -1
- package/components/input/input.d.ts +3 -3
- package/components/input/input.js.map +1 -1
- package/components/mask-input/mask-history.d.ts +22 -18
- package/components/mask-input/mask-history.js.map +1 -1
- package/components/mask-input/mask-input.d.ts +1 -1
- package/components/mask-input/mask-parser.d.ts +11 -13
- package/components/mask-input/mask-parser.js.map +1 -1
- package/components/popover/popover.d.ts +45 -34
- package/components/popover/popover.js +54 -122
- package/components/popover/popover.js.map +1 -1
- package/components/popover/position/arrow.d.ts +19 -0
- package/components/popover/position/arrow.js +33 -0
- package/components/popover/position/arrow.js.map +1 -0
- package/components/popover/position/floating.d.ts +40 -0
- package/components/popover/position/floating.js +146 -0
- package/components/popover/position/floating.js.map +1 -0
- package/components/popover/position/native.d.ts +45 -0
- package/components/popover/position/native.js +158 -0
- package/components/popover/position/native.js.map +1 -0
- package/components/popover/position/strategy.d.ts +37 -0
- package/components/popover/position/strategy.js +21 -0
- package/components/popover/position/strategy.js.map +1 -0
- package/components/popover/position/types.d.ts +26 -0
- package/components/popover/position/types.js +15 -0
- package/components/popover/position/types.js.map +1 -0
- package/components/popover/themes/light/popover.base.css.js +1 -1
- package/components/popover/themes/light/popover.base.css.js.map +1 -1
- package/components/progress/circular-progress.d.ts +0 -5
- package/components/progress/circular-progress.js.map +1 -1
- package/components/qr-code/qr-code.d.ts +1 -1
- package/components/radio/radio.d.ts +6 -4
- package/components/radio/radio.js +24 -25
- package/components/radio/radio.js.map +1 -1
- package/components/radio-group/radio-group.js.map +1 -1
- package/components/rating/rating.d.ts +9 -6
- package/components/rating/rating.js +17 -18
- package/components/rating/rating.js.map +1 -1
- package/components/select/select-group.d.ts +5 -10
- package/components/select/select-group.js +10 -34
- package/components/select/select-group.js.map +1 -1
- package/components/select/select.d.ts +12 -20
- package/components/select/select.js +5 -15
- package/components/select/select.js.map +1 -1
- package/components/slider/range-slider.d.ts +0 -1
- package/components/slider/range-slider.js +6 -11
- package/components/slider/range-slider.js.map +1 -1
- package/components/slider/slider-base.d.ts +4 -1
- package/components/slider/slider-base.js +20 -18
- package/components/slider/slider-base.js.map +1 -1
- package/components/slider/slider.d.ts +2 -0
- package/components/slider/slider.js +5 -1
- package/components/slider/slider.js.map +1 -1
- package/components/splitter/splitter.d.ts +6 -6
- package/components/splitter/splitter.js.map +1 -1
- package/components/textarea/textarea.d.ts +2 -5
- package/components/textarea/textarea.js +3 -5
- package/components/textarea/textarea.js.map +1 -1
- package/components/tile-manager/tile-manager.d.ts +6 -7
- package/components/tile-manager/tile-manager.js.map +1 -1
- package/components/tile-manager/tile.d.ts +3 -3
- package/components/tile-manager/tile.js.map +1 -1
- package/components/toast/toast.d.ts +0 -2
- package/components/toast/toast.js.map +1 -1
- package/components/tooltip/controller.js.map +1 -1
- package/components/tooltip/service.js +4 -5
- package/components/tooltip/service.js.map +1 -1
- package/components/tooltip/tooltip.d.ts +34 -13
- package/components/tooltip/tooltip.js +8 -4
- package/components/tooltip/tooltip.js.map +1 -1
- package/components/tree/tree-item.d.ts +6 -6
- package/components/tree/tree-item.js.map +1 -1
- package/components/tree/tree.navigation.d.ts +5 -6
- package/components/tree/tree.navigation.js.map +1 -1
- package/components/tree/tree.selection.js.map +1 -1
- package/components/types.d.ts +1 -1
- package/components/types.js.map +1 -1
- package/components/validation-container/validation-container.js +2 -1
- package/components/validation-container/validation-container.js.map +1 -1
- package/components/virtualization/engine.d.ts +40 -9
- package/components/virtualization/engine.js +126 -61
- package/components/virtualization/engine.js.map +1 -1
- package/components/virtualization/recycle.d.ts +13 -0
- package/components/virtualization/recycle.js +152 -0
- package/components/virtualization/recycle.js.map +1 -0
- package/components/virtualization/virtualization.d.ts +84 -65
- package/components/virtualization/virtualization.js +20 -16
- package/components/virtualization/virtualization.js.map +1 -1
- package/custom-elements.json +18455 -19551
- package/igniteui-webcomponents.css-data.json +2 -2
- package/igniteui-webcomponents.html-data.json +1 -1
- package/index.d.ts +3 -1
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/internals/abort-handler.d.ts +13 -25
- package/internals/abort-handler.js +4 -6
- package/internals/abort-handler.js.map +1 -1
- package/internals/context.d.ts +13 -7
- package/internals/context.js +2 -1
- package/internals/context.js.map +1 -1
- package/internals/controllers/adopt-styles.d.ts +19 -20
- package/internals/controllers/adopt-styles.js +3 -8
- package/internals/controllers/adopt-styles.js.map +1 -1
- package/internals/controllers/aria-projection.d.ts +100 -61
- package/internals/controllers/aria-projection.js +81 -31
- package/internals/controllers/aria-projection.js.map +1 -1
- package/internals/controllers/async-consumer.js.map +1 -1
- package/internals/controllers/command.d.ts +15 -30
- package/internals/controllers/command.js +2 -7
- package/internals/controllers/command.js.map +1 -1
- package/internals/controllers/context-provider.d.ts +7 -13
- package/internals/controllers/context-provider.js.map +1 -1
- package/internals/controllers/focus-ring.d.ts +10 -30
- package/internals/controllers/focus-ring.js +6 -12
- package/internals/controllers/focus-ring.js.map +1 -1
- package/internals/controllers/fullscreen.d.ts +7 -23
- package/internals/controllers/fullscreen.js +3 -9
- package/internals/controllers/fullscreen.js.map +1 -1
- package/internals/controllers/gestures.d.ts +10 -29
- package/internals/controllers/gestures.js +1 -3
- package/internals/controllers/gestures.js.map +1 -1
- package/internals/controllers/group.d.ts +13 -30
- package/internals/controllers/group.js.map +1 -1
- package/internals/controllers/host-listeners.d.ts +28 -0
- package/internals/controllers/host-listeners.js +27 -0
- package/internals/controllers/host-listeners.js.map +1 -0
- package/internals/controllers/id-resolver.d.ts +8 -9
- package/internals/controllers/id-resolver.js +6 -14
- package/internals/controllers/id-resolver.js.map +1 -1
- package/internals/controllers/internals.d.ts +53 -104
- package/internals/controllers/internals.js +40 -13
- package/internals/controllers/internals.js.map +1 -1
- package/internals/controllers/key-bindings.d.ts +61 -158
- package/internals/controllers/key-bindings.js +68 -67
- package/internals/controllers/key-bindings.js.map +1 -1
- package/internals/controllers/keys.d.ts +32 -0
- package/internals/controllers/keys.js +20 -0
- package/internals/controllers/keys.js.map +1 -0
- package/internals/controllers/mutation-observer.d.ts +14 -37
- package/internals/controllers/mutation-observer.js +1 -1
- package/internals/controllers/mutation-observer.js.map +1 -1
- package/internals/controllers/resize-observer.d.ts +9 -19
- package/internals/controllers/resize-observer.js.map +1 -1
- package/internals/controllers/root-click.d.ts +11 -42
- package/internals/controllers/root-click.js +4 -6
- package/internals/controllers/root-click.js.map +1 -1
- package/internals/controllers/roving-focus.d.ts +16 -35
- package/internals/controllers/roving-focus.js.map +1 -1
- package/internals/controllers/slot.d.ts +25 -54
- package/internals/controllers/slot.js +6 -6
- package/internals/controllers/slot.js.map +1 -1
- package/internals/controllers/toggle.d.ts +44 -48
- package/internals/controllers/toggle.js.map +1 -1
- package/internals/date/compare.js.map +1 -1
- package/internals/date/converters.d.ts +10 -7
- package/internals/date/converters.js.map +1 -1
- package/internals/date/model.d.ts +9 -16
- package/internals/date/model.js +22 -25
- package/internals/date/model.js.map +1 -1
- package/internals/decorators/blazorAdditionalDependencies.d.ts +4 -2
- package/internals/decorators/blazorAdditionalDependencies.js.map +1 -1
- package/internals/decorators/blazorDeepImport.d.ts +1 -3
- package/internals/decorators/blazorDeepImport.js.map +1 -1
- package/internals/decorators/blazorInclude.d.ts +3 -2
- package/internals/decorators/blazorInclude.js.map +1 -1
- package/internals/decorators/blazorIndirectRender.d.ts +1 -3
- package/internals/decorators/blazorIndirectRender.js.map +1 -1
- package/internals/decorators/blazorSuppressComponent.d.ts +1 -3
- package/internals/decorators/blazorSuppressComponent.js.map +1 -1
- package/internals/decorators/coerced-property.d.ts +14 -20
- package/internals/decorators/coerced-property.js.map +1 -1
- package/internals/decorators/shadow-options.d.ts +2 -5
- package/internals/decorators/shadow-options.js.map +1 -1
- package/internals/definitions/defineAllComponents.js +2 -0
- package/internals/definitions/defineAllComponents.js.map +1 -1
- package/internals/directives/drag.d.ts +51 -81
- package/internals/directives/drag.js +27 -89
- package/internals/directives/drag.js.map +1 -1
- package/internals/directives/pointer-operation.d.ts +75 -0
- package/internals/directives/pointer-operation.js +92 -0
- package/internals/directives/pointer-operation.js.map +1 -0
- package/internals/directives/resize.d.ts +36 -64
- package/internals/directives/resize.js +18 -85
- package/internals/directives/resize.js.map +1 -1
- package/internals/i18n/EN/calendar.resources.d.ts +8 -2
- package/internals/i18n/EN/calendar.resources.js +2 -2
- package/internals/i18n/EN/calendar.resources.js.map +1 -1
- package/internals/i18n/EN/chat.resources.d.ts +8 -2
- package/internals/i18n/EN/chat.resources.js +3 -10
- package/internals/i18n/EN/chat.resources.js.map +1 -1
- package/internals/i18n/EN/date-picker.resources.d.ts +6 -4
- package/internals/i18n/EN/date-picker.resources.js +1 -7
- package/internals/i18n/EN/date-picker.resources.js.map +1 -1
- package/internals/i18n/EN/date-range-picker.resources.d.ts +9 -2
- package/internals/i18n/EN/date-range-picker.resources.js +2 -2
- package/internals/i18n/EN/date-range-picker.resources.js.map +1 -1
- package/internals/i18n/i18n-controller.d.ts +44 -46
- package/internals/i18n/i18n-controller.js +46 -33
- package/internals/i18n/i18n-controller.js.map +1 -1
- package/internals/i18n/utils.d.ts +9 -4
- package/internals/i18n/utils.js +4 -27
- package/internals/i18n/utils.js.map +1 -1
- package/internals/mixins/alert.d.ts +10 -25
- package/internals/mixins/alert.js.map +1 -1
- package/internals/mixins/combo-box.d.ts +21 -11
- package/internals/mixins/combo-box.js +16 -22
- package/internals/mixins/combo-box.js.map +1 -1
- package/internals/mixins/event-emitter.js +9 -11
- package/internals/mixins/event-emitter.js.map +1 -1
- package/internals/mixins/forms/associated-required.d.ts +4 -4
- package/internals/mixins/forms/associated-required.js.map +1 -1
- package/internals/mixins/forms/associated.d.ts +4 -2
- package/internals/mixins/forms/associated.js +42 -19
- package/internals/mixins/forms/associated.js.map +1 -1
- package/internals/mixins/forms/form-transformers.js.map +1 -1
- package/internals/mixins/forms/types.d.ts +27 -78
- package/internals/mixins/forms/types.js.map +1 -1
- package/internals/mixins/group.d.ts +18 -0
- package/internals/mixins/group.js +37 -0
- package/internals/mixins/group.js.map +1 -0
- package/internals/mixins/i18n.d.ts +10 -16
- package/internals/mixins/i18n.js.map +1 -1
- package/internals/mixins/mask-behavior.d.ts +8 -22
- package/internals/mixins/mask-behavior.js +1 -2
- package/internals/mixins/mask-behavior.js.map +1 -1
- package/internals/mixins/option.d.ts +1 -2
- package/internals/mixins/option.js +2 -1
- package/internals/mixins/option.js.map +1 -1
- package/internals/part-map.d.ts +4 -2
- package/internals/part-map.js +1 -1
- package/internals/part-map.js.map +1 -1
- package/internals/templates/input-shell.d.ts +8 -17
- package/internals/templates/input-shell.js +4 -1
- package/internals/templates/input-shell.js.map +1 -1
- package/internals/templates/masked-input.d.ts +7 -8
- package/internals/templates/masked-input.js.map +1 -1
- package/internals/templates/slotted-icon.d.ts +7 -12
- package/internals/templates/slotted-icon.js.map +1 -1
- package/internals/templates/toggle-shell.d.ts +19 -19
- package/internals/templates/toggle-shell.js +12 -8
- package/internals/templates/toggle-shell.js.map +1 -1
- package/internals/timing.d.ts +5 -14
- package/internals/timing.js.map +1 -1
- package/internals/utils/arrays.d.ts +21 -21
- package/internals/utils/arrays.js +14 -0
- package/internals/utils/arrays.js.map +1 -1
- package/internals/utils/dom.d.ts +53 -41
- package/internals/utils/dom.js +3 -4
- package/internals/utils/dom.js.map +1 -1
- package/internals/utils/events.d.ts +29 -16
- package/internals/utils/events.js +9 -1
- package/internals/utils/events.js.map +1 -1
- package/internals/utils/lit.d.ts +5 -2
- package/internals/utils/lit.js.map +1 -1
- package/internals/utils/math.d.ts +8 -6
- package/internals/utils/math.js.map +1 -1
- package/internals/utils/objects.d.ts +3 -20
- package/internals/utils/objects.js +1 -39
- package/internals/utils/objects.js.map +1 -1
- package/internals/utils/strings.d.ts +9 -11
- package/internals/utils/strings.js.map +1 -1
- package/internals/utils/types.d.ts +16 -3
- package/internals/utils/types.js +3 -0
- package/internals/utils/types.js.map +1 -1
- package/internals/validators.d.ts +9 -8
- package/internals/validators.js +12 -6
- package/internals/validators.js.map +1 -1
- package/package.json +1 -1
- package/skills/README.md +4 -3
- package/skills/igniteui-wc-choose-components/SKILL.md +2 -1
- package/skills/igniteui-wc-customize-component-theme/SKILL.md +2 -1
- package/skills/igniteui-wc-figma-to-app/SKILL.md +328 -0
- package/skills/igniteui-wc-figma-to-app/references/asset-extraction.md +343 -0
- package/skills/igniteui-wc-figma-to-app/references/design-provenance.md +199 -0
- package/skills/igniteui-wc-figma-to-app/references/design-token-bridge.md +489 -0
- package/skills/igniteui-wc-figma-to-app/references/figma-component-map.md +370 -0
- package/skills/igniteui-wc-figma-to-app/references/figma-exploration.md +222 -0
- package/skills/igniteui-wc-figma-to-app/references/mcp-setup.md +363 -0
- package/skills/igniteui-wc-figma-to-app/references/project-setup.md +105 -0
- package/skills/igniteui-wc-figma-to-app/references/theme-generation.md +180 -0
- package/skills/igniteui-wc-figma-to-app/references/validation-patterns.md +370 -0
- package/skills/igniteui-wc-generate-from-image-design/SKILL.md +2 -1
- package/skills/igniteui-wc-generate-from-image-design/references/gotchas.md +3 -3
- package/skills/igniteui-wc-grids/SKILL.md +133 -0
- package/skills/igniteui-wc-integrate-with-framework/SKILL.md +2 -1
- package/skills/igniteui-wc-migrate-grid-lite-to-premium/SKILL.md +2 -1
- package/skills/igniteui-wc-optimize-bundle-size/SKILL.md +2 -1
- package/theming/config.d.ts +14 -5
- package/theming/config.js +38 -18
- package/theming/config.js.map +1 -1
- package/theming/context.d.ts +1 -23
- package/theming/context.js.map +1 -1
- package/theming/theming-controller.d.ts +2 -32
- package/theming/theming-controller.js +15 -21
- package/theming/theming-controller.js.map +1 -1
- package/theming/theming-event.d.ts +0 -7
- package/theming/theming-event.js +0 -13
- package/theming/theming-event.js.map +1 -1
- package/theming/types.d.ts +1 -8
- package/theming/types.js.map +1 -1
- package/web-types.json +3 -3
- package/animations/presets/slide/index.d.ts +0 -3
- package/animations/presets/slide/index.js +0 -16
- package/animations/presets/slide/index.js.map +0 -1
- package/components/resize-container/themes/resize-container.base.css.js.map +0 -1
- package/internals/controllers/root-scroll.d.ts +0 -31
- package/internals/controllers/root-scroll.js +0 -71
- package/internals/controllers/root-scroll.js.map +0 -1
- package/theming/utils.d.ts +0 -11
- package/theming/utils.js +0 -20
- package/theming/utils.js.map +0 -1
- /package/components/{resize-container/themes/resize-container.base.css.d.ts → breadcrumb/themes/breadcrumb.base.css.d.ts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/components/virtualization/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAOjD,MAAM,oBAAoB,GAAG,IAAI,OAAO,EAAoB,CAAC;AAK7D,SAAS,wBAAwB,CAAC,GAAa;IAC7C,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,eAAe,CAAC;IAClD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,MAAM,CAAC,iBAAiB,CAAC;IAClC,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;IAChC,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC;IAC/C,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;IACtB,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC;IACvB,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC;IAChC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,YAAY,GAAG,GAAG,CAAC,eAAe,EAAE,SAAS,IAAI,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;IACtE,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAE3B,oBAAoB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC;AAMD,SAAS,UAAU,CAAC,KAAa,EAAE,MAAc;IAC/C,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;AACrC,CAAC;AAOD,SAAS,SAAS,CAAC,IAAkB,EAAE,KAAmB;IACxD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACxB,KAAK,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAOD,MAAM,QAAQ;IAwBZ,YACE,MAAc,EACd,KAAmB,EACnB,IAAkB,EAClB,KAAa,EACb,QAAoB;QAEpB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAMM,MAAM,CAAC,MAAM,CAAC,MAAc,EAAE,QAAgB;QACnD,OAAO,QAAQ,CAAC,MAAM,CACpB,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EACvC,IAAI,UAAU,CAAC,MAAM,CAAC,CACvB,CAAC;IACJ,CAAC;IAKO,MAAM,CAAC,MAAM,CAAC,KAAmB,EAAE,QAAoB;QAC7D,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACrC,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC;IAGD,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAMM,SAAS,CAAC,CAAS;QACxB,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAOM,MAAM,CAAC,KAAa,EAAE,OAAe;QAC1C,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAEpD,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,GAAG,KAAK,OAAO;YAAE,OAAO,KAAK,CAAC;QAElC,MAAM,KAAK,GAAG,OAAO,GAAG,GAAG,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IASM,YAAY,CACjB,SAAiB,EACjB,QAAgB,EAChB,WAAW,GAAG,SAAS;QAEvB,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;QAC5E,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC7C,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnD,OAAO,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IASM,aAAa,CAAC,aAAqB;QACxC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC;gBAC3D,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC;gBAC/B,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAC;QAE3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IAMM,iBAAiB,CAAC,MAAc;QACrC,IAAI,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAE/C,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,SAAS,GAAG,MAAM,CAAC;QAEvB,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;YACvB,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;gBACzD,GAAG,GAAG,IAAI,CAAC;gBACX,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;CACF;AAgBD,MAAM,OAAO,mBAAmB;IAAhC;QACU,oBAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAO3C,kBAAa,GAAG,CAAC,CAAC;QAGlB,UAAK,GAAoB,IAAI,CAAC;QAM/B,iBAAY,GAAwB,IAAI,CAAC;IAsLlD,CAAC;IAnLC,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC;IACpC,CAAC;IAGD,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;IAC1E,CAAC;IAGM,kBAAkB,CAAC,GAAa;QACrC,IAAI,CAAC,eAAe,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IASM,MAAM,CACX,MAAc,EACd,aAAqB,EACrB,WAAW,GAAG,MAAM;QAEpB,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,WAAW,IAAI,MAAM;YAAE,OAAO;QAEnE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;YACrB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC;YAC7D,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAC3C,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;IACxB,CAAC;IAGM,WAAW,CAAC,KAAa,EAAE,IAAY;QAC5C,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC;YAAE,OAAO;QAE7C,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;IACxB,CAAC;IAOM,mBAAmB,CAAC,aAAqB;QAC9C,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC;YAAE,OAAO;QAEtD,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;IACxB,CAAC;IAMM,uBAAuB,CAAC,KAAa;QAC1C,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QAExC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;IAC5D,CAAC;IAOO,mBAAmB,CAAC,YAAoB;QAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAClD,CAAC;IAYM,sBAAsB,CAC3B,KAAa,EACb,YAAoB,EACpB,KAAsB;QAEtB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAErD,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,MAAM,GAAG,SAAS,CAAC;QAEvB,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;YAC9D,MAAM,IAAI,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACnD,CAAC;QAED,OAAO,KAAK,CACV,MAAM,GAAG,IAAI,CAAC,aAAa,EAC3B,CAAC,EACD,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,CACvC,CAAC;IACJ,CAAC;IAQM,aAAa,CAClB,KAAa,EACb,cAAsB,EACtB,YAAoB;QAEpB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAEzD,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;QACnE,MAAM,OAAO,GAAG,SAAS,GAAG,YAAY,CAAC;QAEzC,MAAM,SAAS,GAAG,SAAS,IAAI,SAAS,IAAI,OAAO,IAAI,OAAO,CAAC;QAC/D,MAAM,QAAQ,GAAG,SAAS,IAAI,SAAS,IAAI,OAAO,IAAI,OAAO,CAAC;QAE9D,OAAO,SAAS,IAAI,QAAQ,CAAC;IAC/B,CAAC;IAMM,eAAe,CACpB,cAAsB,EACtB,YAAoB,EACpB,QAAgB;QAEhB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YAChE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC;QACzC,CAAC;QAKD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC;QACrE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,WAAW,GAAG,YAAY,CAAC,CAAC;QAEtE,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;YACzC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC;SAC3D,CAAC;IACJ,CAAC;IAOM,oBAAoB,CAAC,UAAkB,EAAE,QAAgB;QAC9D,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,CAAC;QAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACjE,CAAC;IAEO,mBAAmB;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,aAAa;YAChB,SAAS,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC;IAC7E,CAAC;CACF","sourcesContent":["import { clamp } from '#internals/utils/math.js';\nimport type { ScrollAlignment, VisibleRange } from './types.js';\n\n/**\n * The maximum scrollable coordinate of a document does not change.\n * All instances in one document share one probe result.\n */\nconst _maxBrowserSizeCache = new WeakMap<Document, number>();\n\n/**\n * Measures the maximum scrollable coordinate that the browser supports.\n */\nfunction getMaxBrowserSizeProbePx(doc: Document): number {\n const cached = _maxBrowserSizeCache.get(doc);\n if (cached !== undefined) {\n return cached;\n }\n\n const container = doc.body ?? doc.documentElement;\n if (!container) {\n return Number.POSITIVE_INFINITY;\n }\n\n const div = doc.createElement('div');\n div.style.position = 'absolute';\n div.style.top = `${Number.MAX_SAFE_INTEGER}px`;\n div.style.width = '0';\n div.style.height = '0';\n div.style.visibility = 'hidden';\n container.appendChild(div);\n const scrollOffset = doc.documentElement?.scrollTop ?? 0;\n const size = Math.abs(div.getBoundingClientRect().top) + scrollOffset;\n container.removeChild(div);\n\n _maxBrowserSizeCache.set(doc, size);\n return size;\n}\n\n/**\n * Clamps `index` into `[0, length - 1]`. This keeps `prefixSum(index)` and\n * `prefixSum(index + 1)` valid. Callers make sure that `length > 0`.\n */\nfunction clampIndex(index: number, length: number): number {\n return clamp(index, 0, length - 1);\n}\n\n/**\n * Fills `tree` with the partial range sums of `sizes` in one O(N) pass.\n * `tree` is a 1-indexed Fenwick array of `sizes.length + 1` zeroed entries.\n * Returns the total sum.\n */\nfunction buildTree(tree: Float64Array, sizes: Float64Array): number {\n const length = sizes.length;\n let total = 0;\n\n for (let i = 1; i <= length; i++) {\n tree[i] += sizes[i - 1];\n total += sizes[i - 1];\n const j = i + (i & -i);\n if (j <= length) {\n tree[j] += tree[i];\n }\n }\n return total;\n}\n\n/**\n * Binary Indexed Tree (Fenwick tree) over item sizes. Each hot-path operation\n * is O(log N): point update (item measured), prefix sum (scroll offset), and\n * index at offset (scroll to item, through binary lifting).\n */\nclass SizeTree {\n public readonly length: number;\n\n /** A 1-indexed BIT. Each cell holds a partial range sum. */\n private readonly _tree: Float64Array;\n\n /** Raw per-item sizes, 0-indexed. Kept for O(1) reads and delta calculation. */\n private readonly _sizes: Float64Array;\n\n /**\n * Flags the indices that hold a DOM-measured size (`1`) instead of an\n * estimate (`0`). `applyEstimate` changes only the estimated entries.\n */\n private readonly _measured: Uint8Array;\n\n /** Running total. Updated together with the tree in O(1). */\n private _total: number;\n\n /**\n * The highest power of two <= `length`, for the binary lifting in\n * `findIndexAtOffset`. Precomputed because that runs on each scroll event.\n */\n private readonly _topBit: number;\n\n private constructor(\n length: number,\n sizes: Float64Array,\n tree: Float64Array,\n total: number,\n measured: Uint8Array\n ) {\n this.length = length;\n this._sizes = sizes;\n this._tree = tree;\n this._total = total;\n this._measured = measured;\n this._topBit = length > 0 ? 1 << (31 - Math.clz32(length)) : 0;\n }\n\n /**\n * Creates a tree of `length` items, each set to `fillSize` and marked\n * unmeasured. O(N).\n */\n public static filled(length: number, fillSize: number): SizeTree {\n return SizeTree._build(\n new Float64Array(length).fill(fillSize),\n new Uint8Array(length)\n );\n }\n\n /**\n * Builds a tree from a sizes array and its matching measured-flags array. O(N).\n */\n private static _build(sizes: Float64Array, measured: Uint8Array): SizeTree {\n const tree = new Float64Array(sizes.length + 1);\n const total = buildTree(tree, sizes);\n return new SizeTree(sizes.length, sizes, tree, total, measured);\n }\n\n /** Total size of all items. O(1). */\n public get totalSize(): number {\n return this._total;\n }\n\n /**\n * Prefix sum of items [0, i): the virtual scroll offset at the leading\n * edge of item i. O(log N).\n */\n public prefixSum(i: number): number {\n let sum = 0;\n for (let j = i; j > 0; j -= j & -j) {\n sum += this._tree[j];\n }\n return sum;\n }\n\n /**\n * Sets the size of the item at a 0-based index and marks the item as\n * measured. Later `applyEstimate()` calls do not change measured items.\n * Returns true when the size changed. O(log N).\n */\n public update(index: number, newSize: number): boolean {\n if (index < 0 || index >= this.length) return false;\n\n const old = this._sizes[index];\n this._measured[index] = 1;\n if (old === newSize) return false;\n\n const delta = newSize - old;\n this._sizes[index] = newSize;\n this._total += delta;\n for (let i = index + 1; i <= this.length; i += i & -i) {\n this._tree[i] += delta;\n }\n return true;\n }\n\n /**\n * Returns a new tree of `newLength` items in one O(N) pass. Sizes and\n * measured flags are kept up to `min(this.length, newLength, retainCount)`.\n * The remainder is filled with `fillSize` and marked unmeasured. Pass a\n * `retainCount` below the item count when the data behind those indices\n * changed identity.\n */\n public cloneResized(\n newLength: number,\n fillSize: number,\n retainCount = newLength\n ): SizeTree {\n const sizes = new Float64Array(newLength).fill(fillSize);\n const measured = new Uint8Array(newLength);\n const retained = Math.max(0, Math.min(this.length, newLength, retainCount));\n sizes.set(this._sizes.subarray(0, retained));\n measured.set(this._measured.subarray(0, retained));\n return SizeTree._build(sizes, measured);\n }\n\n /**\n * Sets `estimatedSize` on each unmeasured item. Measured items do not\n * change. Returns true when at least one size changed.\n *\n * One estimate change can touch most of the list, so this rebuilds in one\n * O(N) pass instead of one O(log N) `update` per item.\n */\n public applyEstimate(estimatedSize: number): boolean {\n let changed = false;\n for (let i = 0; i < this.length; i++) {\n if (!this._measured[i] && this._sizes[i] !== estimatedSize) {\n this._sizes[i] = estimatedSize;\n changed = true;\n }\n }\n if (!changed) return false;\n\n this._tree.fill(0);\n this._total = buildTree(this._tree, this._sizes);\n return true;\n }\n\n /**\n * Returns the 0-based index of the item that contains the scroll `offset`:\n * the largest i where `prefixSum(i) <= offset < prefixSum(i + 1)`. O(log N).\n */\n public findIndexAtOffset(offset: number): number {\n if (offset <= 0 || this.length === 0) return 0;\n\n let idx = 0;\n let remaining = offset;\n\n for (let bit = this._topBit; bit > 0; bit >>= 1) {\n const next = idx + bit;\n if (next <= this.length && this._tree[next] <= remaining) {\n idx = next;\n remaining -= this._tree[idx];\n }\n }\n return Math.min(this.length - 1, idx);\n }\n}\n\n/**\n * Pure scroll-math engine for one axis of virtual scrolling. A Fenwick tree\n * holds all size state.\n *\n * ### Virtual and DOM coordinates\n *\n * Browsers limit how far an element can scroll. When the total item size is\n * larger than that limit, the engine compresses the *virtual* space\n * (`0…totalSize`) into the *DOM* space the browser can represent\n * (`0…domSize`) by the factor `_virtualRatio`. Each offset that crosses that\n * boundary is scaled: incoming scroll positions are multiplied by the ratio,\n * and outgoing offsets are divided by it. Items render at their real pixel\n * size, so item sizes are always virtual.\n */\nexport class VirtualScrollEngine {\n private _maxBrowserSize = Number.POSITIVE_INFINITY;\n\n /**\n * The ratio `totalSize / maxBrowserSize` when `totalSize` is larger than\n * the maximum DOM coordinate the browser supports; `1` otherwise.\n * Maps virtual scroll positions to DOM scroll positions.\n */\n private _virtualRatio = 1;\n\n /** Binary Indexed Tree for O(log N) size queries and updates. */\n private _tree: SizeTree | null = null;\n\n /**\n * Called when item sizes or the item count change.\n * Example: `() => this.requestUpdate()`.\n */\n public onSizeChange: (() => void) | null = null;\n\n /** Total virtual size of all items in px. */\n public get totalSize(): number {\n return this._tree?.totalSize ?? 0;\n }\n\n /** Total size in DOM space, clamped to the maximum browser size. */\n public get domSize(): number {\n return this._virtualRatio !== 1 ? this._maxBrowserSize : this.totalSize;\n }\n\n /** Measures the maximum browser size for the document and rescales. */\n public initMaxBrowserSize(doc: Document): void {\n this._maxBrowserSize = getMaxBrowserSizeProbePx(doc);\n this._updateVirtualRatio();\n }\n\n /**\n * Resizes the internal sizes array to `length`. Measured sizes below\n * `retainCount` are kept. The remainder is filled with `estimatedSize` and\n * marked unmeasured. Callers that only append can keep the default\n * `retainCount`. Callers whose data changed identity at some index must\n * pass that index, so the stale measurements after it are discarded.\n */\n public resize(\n length: number,\n estimatedSize: number,\n retainCount = length\n ): void {\n if (this._tree?.length === length && retainCount >= length) return;\n\n this._tree = this._tree\n ? this._tree.cloneResized(length, estimatedSize, retainCount)\n : SizeTree.filled(length, estimatedSize);\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /** Records the measured DOM size for a single item. */\n public measureItem(index: number, size: number): void {\n if (!this._tree?.update(index, size)) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /**\n * Applies a new estimated size to each item that is not measured in the\n * DOM. Use this when `estimatedItemSize` changes but the item count does\n * not, because `resize` is then a no-op.\n */\n public updateEstimatedSize(estimatedSize: number): void {\n if (!this._tree?.applyEstimate(estimatedSize)) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /**\n * Returns the DOM scroll offset in px that puts the item at `index` at the\n * leading edge of the viewport.\n */\n public getScrollOffsetForIndex(index: number): number {\n if (!this._tree || index <= 0) return 0;\n\n const clamped = Math.min(index, this._tree.length);\n return this._tree.prefixSum(clamped) / this._virtualRatio;\n }\n\n /**\n * The largest DOM scroll offset the host can reach for the given viewport\n * size. A request beyond it does nothing, so offsets given to a caller\n * that waits for the scroll to settle are clamped to it.\n */\n private _getMaxScrollOffset(viewportSize: number): number {\n return Math.max(0, this.domSize - viewportSize);\n }\n\n /**\n * Returns the DOM scroll offset that positions the item at `index` in a\n * `viewportSize` px viewport, aligned by `align` and clamped to the\n * reachable scroll range.\n *\n * The slack is computed in virtual space against the item's real size and\n * converted to DOM space once, at the end. One DOM pixel equals\n * `_virtualRatio` virtual pixels, so mixed coordinates would scale the\n * slack.\n */\n public getAlignedScrollOffset(\n index: number,\n viewportSize: number,\n align: ScrollAlignment\n ): number {\n if (!this._tree || this._tree.length === 0) return 0;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n let offset = itemStart;\n\n if (align !== 'start') {\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const slack = viewportSize - Math.max(0, itemEnd - itemStart);\n offset -= align === 'center' ? slack / 2 : slack;\n }\n\n return clamp(\n offset / this._virtualRatio,\n 0,\n this._getMaxScrollOffset(viewportSize)\n );\n }\n\n /**\n * Whether the item at `index` is visible without more scrolling at the\n * given DOM scroll position. True when the item is fully inside the\n * viewport, or when it is larger than the viewport and covers it fully.\n * The second case matches native `scrollIntoView({ block: 'nearest' })`.\n */\n public isIndexInView(\n index: number,\n scrollPosition: number,\n viewportSize: number\n ): boolean {\n if (!this._tree || this._tree.length === 0) return false;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const viewStart = Math.max(0, scrollPosition) * this._virtualRatio;\n const viewEnd = viewStart + viewportSize;\n\n const contained = itemStart >= viewStart && itemEnd <= viewEnd;\n const spanning = itemStart <= viewStart && itemEnd >= viewEnd;\n\n return contained || spanning;\n }\n\n /**\n * Returns the visible and over-scanned item range for the given scroll\n * state.\n */\n public getVisibleRange(\n scrollPosition: number,\n viewportSize: number,\n overScan: number\n ): VisibleRange {\n if (!this._tree || this._tree.length === 0 || viewportSize <= 0) {\n return { startIndex: 0, endIndex: -1 };\n }\n\n // The viewport is not scaled by the virtual ratio. Items render at their\n // real pixel size, so a `viewportSize` px viewport always shows that many\n // virtual pixels of items, at any compression of the scroll range.\n const startOffset = Math.max(0, scrollPosition) * this._virtualRatio;\n const first = this._tree.findIndexAtOffset(startOffset);\n const last = this._tree.findIndexAtOffset(startOffset + viewportSize);\n\n return {\n startIndex: Math.max(0, first - overScan),\n endIndex: Math.min(this._tree.length - 1, last + overScan),\n };\n }\n\n /**\n * Sum of the actual sizes of the items in [startIndex, endIndex]. The\n * render pass uses it to clamp the content translate offset, so rendered\n * items do not overflow past `domSize` under coordinate compression.\n */\n public getPhysicalRangeSize(startIndex: number, endIndex: number): number {\n if (!this._tree) return 0;\n\n const start = Math.max(0, startIndex);\n const end = Math.min(Math.max(endIndex + 1, start), this._tree.length);\n return this._tree.prefixSum(end) - this._tree.prefixSum(start);\n }\n\n private _updateVirtualRatio(): void {\n const totalSize = this._tree?.totalSize ?? 0;\n this._virtualRatio =\n totalSize <= this._maxBrowserSize ? 1 : totalSize / this._maxBrowserSize;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/components/virtualization/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { clamp } from '#internals/utils/math.js';\nimport type { ScrollAlignment, VisibleRange } from './types.js';\n\n/**\n * The maximum scrollable coordinate of a document does not change.\n * All instances in one document share one probe result.\n */\nconst _maxBrowserSizeCache = new WeakMap<Document, number>();\n\n/**\n * Measures the maximum scrollable coordinate that the browser supports.\n */\nfunction getMaxBrowserSizeProbePx(doc: Document): number {\n const cached = _maxBrowserSizeCache.get(doc);\n if (cached !== undefined) {\n return cached;\n }\n\n const container = doc.body ?? doc.documentElement;\n if (!container) {\n return Number.POSITIVE_INFINITY;\n }\n\n const div = doc.createElement('div');\n div.style.position = 'absolute';\n div.style.top = `${Number.MAX_SAFE_INTEGER}px`;\n div.style.width = '0';\n div.style.height = '0';\n div.style.visibility = 'hidden';\n container.appendChild(div);\n const scrollOffset = doc.documentElement?.scrollTop ?? 0;\n const size = Math.abs(div.getBoundingClientRect().top) + scrollOffset;\n container.removeChild(div);\n\n _maxBrowserSizeCache.set(doc, size);\n return size;\n}\n\n/**\n * Clamps `index` into `[0, length - 1]`. This keeps `prefixSum(index)` and\n * `prefixSum(index + 1)` valid. Callers make sure that `length > 0`.\n */\nfunction clampIndex(index: number, length: number): number {\n return clamp(index, 0, length - 1);\n}\n\n/** The item holds the estimate. */\nconst UNMEASURED = 0;\n/** The item was measured under an older estimate. */\nconst MEASURED = 1;\n/** The item was measured under the current estimate. */\nconst SAMPLED = 2;\n\n/**\n * Binary Indexed Tree (Fenwick tree) over item sizes. Each hot-path operation\n * is O(log N): point update (item measured), prefix sum (scroll offset), and\n * index at offset (scroll to item, through binary lifting).\n *\n * The tree holds only the measured sizes and the number of measured items.\n * Each unmeasured item counts as `estimate`, so an estimate change is O(1).\n */\nclass SizeTree {\n public readonly length: number;\n\n /** The size of each unmeasured item. */\n public estimate: number;\n\n /** A 1-indexed BIT of the measured sizes. */\n private readonly _sums: Float64Array;\n\n /** A 1-indexed BIT of the number of measured items. */\n private readonly _counts: Int32Array;\n\n /** Raw measured sizes, 0-indexed. Kept for O(1) delta calculation. */\n private readonly _sizes: Float64Array;\n\n /** `UNMEASURED`, `MEASURED` or `SAMPLED` for each item. */\n private readonly _states: Uint8Array;\n\n private _measuredCount = 0;\n private _measuredTotal = 0;\n\n /** Count and size sum of the `SAMPLED` items. */\n private _sampleCount = 0;\n private _sampleTotal = 0;\n\n /**\n * The highest power of two <= `length`, for the binary lifting in\n * `findIndexAtOffset`. Precomputed because that runs on each scroll event.\n */\n private readonly _topBit: number;\n\n /** Builds the tree in one O(N) pass. Without `states`, no item is measured. */\n constructor(\n length: number,\n estimate: number,\n sizes = new Float64Array(length),\n states = new Uint8Array(length)\n ) {\n this.length = length;\n this.estimate = estimate;\n this._sizes = sizes;\n this._states = states;\n this._sums = new Float64Array(length + 1);\n this._counts = new Int32Array(length + 1);\n this._topBit = length > 0 ? 1 << (31 - Math.clz32(length)) : 0;\n\n for (let i = 1; i <= length; i++) {\n const state = states[i - 1];\n\n if (state !== UNMEASURED) {\n const size = sizes[i - 1];\n this._sums[i] += size;\n this._counts[i]++;\n this._measuredCount++;\n this._measuredTotal += size;\n\n if (state === SAMPLED) {\n this._sampleCount++;\n this._sampleTotal += size;\n }\n }\n\n const parent = i + (i & -i);\n if (parent <= length) {\n this._sums[parent] += this._sums[i];\n this._counts[parent] += this._counts[i];\n }\n }\n }\n\n /** Total size of all items. O(1). */\n public get totalSize(): number {\n return (\n this._measuredTotal + (this.length - this._measuredCount) * this.estimate\n );\n }\n\n /** The average size of the `SAMPLED` items, or `0` if there are none. */\n public get sampleAverage(): number {\n return this._sampleCount > 0 ? this._sampleTotal / this._sampleCount : 0;\n }\n\n /** Whether each item before `index` is measured. O(log N). */\n public isMeasuredBefore(index: number): boolean {\n let count = 0;\n for (let j = index; j > 0; j -= j & -j) {\n count += this._counts[j];\n }\n return count === index;\n }\n\n /**\n * Prefix sum of items [0, i): the virtual scroll offset at the leading\n * edge of item i. O(log N).\n */\n public prefixSum(i: number): number {\n let sum = 0;\n let count = 0;\n for (let j = i; j > 0; j -= j & -j) {\n sum += this._sums[j];\n count += this._counts[j];\n }\n return sum + (i - count) * this.estimate;\n }\n\n /**\n * Sets the size of the item at a 0-based index and marks it `SAMPLED`.\n * Returns true when the size changed. O(log N).\n */\n public update(index: number, size: number): boolean {\n if (index < 0 || index >= this.length) return false;\n\n const state = this._states[index];\n const isNew = state === UNMEASURED;\n const old = isNew ? 0 : this._sizes[index];\n const delta = size - old;\n\n this._states[index] = SAMPLED;\n this._sizes[index] = size;\n this._measuredTotal += delta;\n this._sampleTotal += state === SAMPLED ? delta : size;\n if (state !== SAMPLED) this._sampleCount++;\n if (isNew) this._measuredCount++;\n\n if (isNew || delta !== 0) {\n for (let i = index + 1; i <= this.length; i += i & -i) {\n this._sums[i] += delta;\n if (isNew) this._counts[i]++;\n }\n }\n\n return size !== (isNew ? this.estimate : old);\n }\n\n /**\n * Returns a new tree of `newLength` items. Measured sizes are kept up to\n * `min(this.length, newLength, retainCount)`, and the other items are\n * unmeasured. Pass a `retainCount` below the item count when the data\n * behind those indices changed identity. O(N).\n */\n public cloneResized(newLength: number, retainCount = newLength): SizeTree {\n const retained = Math.max(0, Math.min(this.length, newLength, retainCount));\n const sizes = new Float64Array(newLength);\n const states = new Uint8Array(newLength);\n sizes.set(this._sizes.subarray(0, retained));\n states.set(this._states.subarray(0, retained));\n return new SizeTree(newLength, this.estimate, sizes, states);\n }\n\n /**\n * Starts a new sample: `sampleAverage` then counts only the items measured\n * after this call. O(N).\n */\n public startSample(): void {\n for (let i = 0; i < this.length; i++) {\n if (this._states[i] === SAMPLED) {\n this._states[i] = MEASURED;\n }\n }\n this._sampleCount = 0;\n this._sampleTotal = 0;\n }\n\n /**\n * Returns the 0-based index of the item that contains the scroll `offset`:\n * the largest i where `prefixSum(i) <= offset < prefixSum(i + 1)`. O(log N).\n */\n public findIndexAtOffset(offset: number): number {\n if (offset <= 0 || this.length === 0) return 0;\n\n let idx = 0;\n let remaining = offset;\n\n for (let bit = this._topBit; bit > 0; bit >>= 1) {\n const next = idx + bit;\n if (next > this.length) continue;\n\n // Node `next` covers the `bit` items after `idx`.\n const size =\n this._sums[next] + (bit - this._counts[next]) * this.estimate;\n if (size <= remaining) {\n idx = next;\n remaining -= size;\n }\n }\n return Math.min(this.length - 1, idx);\n }\n}\n\n/**\n * Pure scroll-math engine for one axis of virtual scrolling. A Fenwick tree\n * holds all size state.\n *\n * ### Virtual and DOM coordinates\n *\n * Browsers limit how far an element can scroll. When the total item size is\n * larger than that limit, the engine compresses the *virtual* space\n * (`0…totalSize`) into the *DOM* space the browser can represent\n * (`0…domSize`) by the factor `_virtualRatio`. Each offset that crosses that\n * boundary is scaled: incoming scroll positions are multiplied by the ratio,\n * and outgoing offsets are divided by it. Items render at their real pixel\n * size, so item sizes are always virtual.\n */\nexport class VirtualScrollEngine {\n private _maxBrowserSize = Number.POSITIVE_INFINITY;\n\n /**\n * Maps a virtual scroll position to a DOM scroll position. The ratio\n * `totalSize / maxBrowserSize` if `totalSize` is larger than the maximum DOM\n * coordinate of the browser, and `1` in all other cases.\n */\n private _virtualRatio = 1;\n\n /** Binary Indexed Tree for O(log N) size queries and updates. */\n private _tree: SizeTree | null = null;\n\n /** The estimate last given to `resize` or `updateEstimatedSize`. */\n private _configuredEstimate = Number.NaN;\n\n /** Whether `adaptEstimate` has applied a measured average. */\n private _hasAdaptedEstimate = false;\n\n /**\n * Called when item sizes or the item count change.\n * Example: `() => this.requestUpdate()`.\n */\n public onSizeChange: (() => void) | null = null;\n\n /** Total virtual size of all items in px. */\n public get totalSize(): number {\n return this._tree?.totalSize ?? 0;\n }\n\n /** Total size in DOM space, clamped to the maximum browser size. */\n public get domSize(): number {\n return this._virtualRatio !== 1 ? this._maxBrowserSize : this.totalSize;\n }\n\n /** Measures the maximum browser size for the document and rescales. */\n public initMaxBrowserSize(doc: Document): void {\n this._maxBrowserSize = getMaxBrowserSizeProbePx(doc);\n this._updateVirtualRatio();\n }\n\n /**\n * Resizes the internal sizes array to `length`. Measured sizes below\n * `retainCount` are kept, and the other items are unmeasured. Callers that\n * only append can keep the default `retainCount`. Callers whose data\n * changed identity at some index must pass that index, so the stale\n * measurements after it are discarded.\n *\n * Unmeasured items take `estimatedSize`, or the adapted average while\n * `estimatedSize` stays the same: a data change does not make it less\n * accurate.\n */\n public resize(\n length: number,\n estimatedSize: number,\n retainCount = length\n ): void {\n if (this._tree?.length === length && retainCount >= length) return;\n\n const reconfigured = this._configureEstimate(estimatedSize);\n const tree =\n this._tree?.cloneResized(length, retainCount) ??\n new SizeTree(length, estimatedSize);\n\n if (reconfigured) {\n tree.estimate = estimatedSize;\n }\n this._tree = tree;\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /** Records the measured DOM size for a single item. */\n public measureItem(index: number, size: number): void {\n if (!this._tree?.update(index, size)) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /**\n * Applies a new estimated size to each item that is not measured in the\n * DOM. Use this when `estimatedItemSize` changes but the item count does\n * not, because `resize` is then a no-op.\n */\n public updateEstimatedSize(estimatedSize: number): void {\n if (this._configureEstimate(estimatedSize)) {\n this._applyEstimate(estimatedSize);\n }\n }\n\n /**\n * Sets the estimate of the unmeasured items to the average size measured\n * since the estimate was last configured. Older sizes can be out of date,\n * for example after a density change.\n *\n * The first change applies anywhere. A later one applies only while each\n * item before `windowStart` is measured: the offset of the rendered items\n * then does not depend on the estimate, so the change cannot move them.\n */\n public adaptEstimate(windowStart: number): void {\n const tree = this._tree;\n if (!tree?.sampleAverage) return;\n if (this._hasAdaptedEstimate && !tree.isMeasuredBefore(windowStart)) return;\n\n this._hasAdaptedEstimate = true;\n this._applyEstimate(tree.sampleAverage);\n }\n\n /**\n * Returns the DOM scroll offset in px that puts the item at `index` at the\n * leading edge of the viewport.\n */\n public getScrollOffsetForIndex(index: number): number {\n if (!this._tree || index <= 0) return 0;\n\n const clamped = Math.min(index, this._tree.length);\n return this._tree.prefixSum(clamped) / this._virtualRatio;\n }\n\n /**\n * The largest DOM scroll offset the host can reach for the given viewport\n * size. A request past it does nothing, so an offset given to a caller that\n * waits for the scroll to settle is clamped to this value.\n */\n private _getMaxScrollOffset(viewportSize: number): number {\n return Math.max(0, this.domSize - viewportSize);\n }\n\n /**\n * Returns the DOM scroll offset that positions the item at `index` in a\n * `viewportSize` px viewport, aligned by `align` and clamped to the\n * reachable scroll range.\n *\n * The slack is computed in virtual space against the item's real size and\n * converted to DOM space once, at the end. One DOM pixel equals\n * `_virtualRatio` virtual pixels, so mixed coordinates would scale the\n * slack.\n */\n public getAlignedScrollOffset(\n index: number,\n viewportSize: number,\n align: ScrollAlignment\n ): number {\n if (!this._tree || this._tree.length === 0) return 0;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n let offset = itemStart;\n\n if (align !== 'start') {\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const slack = viewportSize - Math.max(0, itemEnd - itemStart);\n offset -= align === 'center' ? slack / 2 : slack;\n }\n\n return clamp(\n offset / this._virtualRatio,\n 0,\n this._getMaxScrollOffset(viewportSize)\n );\n }\n\n /**\n * Returns the DOM scroll offset that brings the item at `index` into view\n * as `position` asks. `nearest` follows native `scrollIntoView`: an item in\n * view, or one that covers the viewport, keeps `scrollPosition`, and any\n * other item scrolls the smallest distance to an edge alignment.\n */\n public resolveScrollOffset(\n index: number,\n scrollPosition: number,\n viewportSize: number,\n position: ScrollLogicalPosition = 'start'\n ): number {\n if (position === 'nearest') {\n const start = this.getAlignedScrollOffset(index, viewportSize, 'start');\n const end = this.getAlignedScrollOffset(index, viewportSize, 'end');\n return clamp(scrollPosition, Math.min(start, end), Math.max(start, end));\n }\n\n return this.getAlignedScrollOffset(\n index,\n viewportSize,\n position === 'center' || position === 'end' ? position : 'start'\n );\n }\n\n /**\n * Whether the item at `index` is visible without more scrolling at the\n * given DOM scroll position. True when the item is fully inside the\n * viewport, or when it is larger than the viewport and covers it fully.\n * The second case matches native `scrollIntoView({ block: 'nearest' })`.\n */\n public isIndexInView(\n index: number,\n scrollPosition: number,\n viewportSize: number\n ): boolean {\n if (!this._tree || this._tree.length === 0) return false;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const viewStart = Math.max(0, scrollPosition) * this._virtualRatio;\n const viewEnd = viewStart + viewportSize;\n\n const contained = itemStart >= viewStart && itemEnd <= viewEnd;\n const spanning = itemStart <= viewStart && itemEnd >= viewEnd;\n\n return contained || spanning;\n }\n\n /**\n * Returns the visible and over-scanned item range for the given scroll\n * state.\n */\n public getVisibleRange(\n scrollPosition: number,\n viewportSize: number,\n overScan: number\n ): VisibleRange {\n if (!this._tree || this._tree.length === 0 || viewportSize <= 0) {\n return { startIndex: 0, endIndex: -1 };\n }\n\n // The virtual ratio does not scale the viewport. Items render at their real\n // pixel size, so a `viewportSize` px viewport shows that many virtual pixels\n // of items at any compression of the scroll range.\n const startOffset = Math.max(0, scrollPosition) * this._virtualRatio;\n const first = this._tree.findIndexAtOffset(startOffset);\n const last = this._tree.findIndexAtOffset(startOffset + viewportSize);\n\n return {\n startIndex: Math.max(0, first - overScan),\n endIndex: Math.min(this._tree.length - 1, last + overScan),\n };\n }\n\n /**\n * Sum of the actual sizes of the items in [startIndex, endIndex]. The\n * render pass uses it to clamp the content translate offset, so rendered\n * items do not overflow past `domSize` under coordinate compression.\n */\n public getPhysicalRangeSize(startIndex: number, endIndex: number): number {\n if (!this._tree) return 0;\n\n const start = Math.max(0, startIndex);\n const end = Math.min(Math.max(endIndex + 1, start), this._tree.length);\n return this._tree.prefixSum(end) - this._tree.prefixSum(start);\n }\n\n /**\n * Records a changed configured estimate and starts a new sample. Returns\n * false for an unchanged one, which keeps the adapted average.\n */\n private _configureEstimate(estimatedSize: number): boolean {\n if (estimatedSize === this._configuredEstimate) return false;\n\n this._configuredEstimate = estimatedSize;\n this._tree?.startSample();\n return true;\n }\n\n private _applyEstimate(estimatedSize: number): void {\n const tree = this._tree;\n if (!tree) return;\n\n const total = tree.totalSize;\n tree.estimate = estimatedSize;\n if (tree.totalSize === total) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n private _updateVirtualRatio(): void {\n const totalSize = this._tree?.totalSize ?? 0;\n this._virtualRatio =\n totalSize <= this._maxBrowserSize ? 1 : totalSize / this._maxBrowserSize;\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ItemTemplate, KeyFn } from 'lit/directives/repeat.js';
|
|
2
|
+
interface RecycleDirectiveFn {
|
|
3
|
+
<T>(items: readonly T[], keyFn: KeyFn<T>, template: ItemTemplate<T>): unknown;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Renders `items` as `repeat` does, but gives the DOM of a key that leaves to
|
|
7
|
+
* a key that arrives. `repeat` destroys the part of each key that leaves and
|
|
8
|
+
* creates one for each key that arrives, which in a scrolling window is DOM
|
|
9
|
+
* churn on each scroll step. A reused part keeps any DOM state that the
|
|
10
|
+
* template does not bind.
|
|
11
|
+
*/
|
|
12
|
+
export declare const recycle: RecycleDirectiveFn;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { noChange, nothing, render } from 'lit';
|
|
2
|
+
import { clearPart, getCommittedValue, insertPart, setChildPartValue, setCommittedValue, } from 'lit/directive-helpers.js';
|
|
3
|
+
import { Directive, directive } from 'lit/directive.js';
|
|
4
|
+
import { getRoot } from '#internals/utils/dom.js';
|
|
5
|
+
const KEPT_WEIGHT = 2;
|
|
6
|
+
function heaviestIncreasingSubsequence(values, weights, size) {
|
|
7
|
+
const heaviest = new Int32Array(size + 1);
|
|
8
|
+
const endsAt = new Int32Array(size + 1);
|
|
9
|
+
const previous = new Int32Array(values.length);
|
|
10
|
+
const marked = new Uint8Array(values.length);
|
|
11
|
+
let best = 0;
|
|
12
|
+
let last = -1;
|
|
13
|
+
for (let i = 0; i < values.length; i++) {
|
|
14
|
+
if (values[i] < 0) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
let total = 0;
|
|
18
|
+
let before = -1;
|
|
19
|
+
for (let node = values[i]; node > 0; node -= node & -node) {
|
|
20
|
+
if (heaviest[node] > total) {
|
|
21
|
+
total = heaviest[node];
|
|
22
|
+
before = endsAt[node];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
total += weights[i];
|
|
26
|
+
previous[i] = before;
|
|
27
|
+
for (let node = values[i] + 1; node <= size; node += node & -node) {
|
|
28
|
+
if (total > heaviest[node]) {
|
|
29
|
+
heaviest[node] = total;
|
|
30
|
+
endsAt[node] = i;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (total > best) {
|
|
34
|
+
best = total;
|
|
35
|
+
last = i;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (let i = last; i >= 0; i = previous[i]) {
|
|
39
|
+
marked[i] = 1;
|
|
40
|
+
}
|
|
41
|
+
return marked;
|
|
42
|
+
}
|
|
43
|
+
function removeItemPart(part) {
|
|
44
|
+
clearPart(part);
|
|
45
|
+
part.startNode.remove();
|
|
46
|
+
part.endNode.remove();
|
|
47
|
+
}
|
|
48
|
+
function focusedPosition(containerPart, parts) {
|
|
49
|
+
const container = containerPart.parentNode;
|
|
50
|
+
let node = getRoot(container).activeElement;
|
|
51
|
+
while (node && node.parentNode !== container) {
|
|
52
|
+
node = node.parentNode;
|
|
53
|
+
}
|
|
54
|
+
if (!node) {
|
|
55
|
+
return -1;
|
|
56
|
+
}
|
|
57
|
+
return parts.findIndex((part) => {
|
|
58
|
+
let n = part.startNode.nextSibling;
|
|
59
|
+
while (n && n !== part.endNode && n !== node) {
|
|
60
|
+
n = n.nextSibling;
|
|
61
|
+
}
|
|
62
|
+
return n === node;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
class RecycleDirective extends Directive {
|
|
66
|
+
constructor() {
|
|
67
|
+
super(...arguments);
|
|
68
|
+
this._keys = [];
|
|
69
|
+
this._pool = [];
|
|
70
|
+
}
|
|
71
|
+
render(items, _keyFn, template) {
|
|
72
|
+
return items.map(template);
|
|
73
|
+
}
|
|
74
|
+
update(containerPart, [items, keyFn, template]) {
|
|
75
|
+
const keys = items.map(keyFn);
|
|
76
|
+
const values = items.map(template);
|
|
77
|
+
const committed = getCommittedValue(containerPart);
|
|
78
|
+
if (!Array.isArray(committed)) {
|
|
79
|
+
this._keys = keys;
|
|
80
|
+
return values;
|
|
81
|
+
}
|
|
82
|
+
setCommittedValue(containerPart, this._reconcile(containerPart, committed, keys, values));
|
|
83
|
+
this._keys = keys;
|
|
84
|
+
return noChange;
|
|
85
|
+
}
|
|
86
|
+
_reconcile(containerPart, oldParts, keys, values) {
|
|
87
|
+
const count = keys.length;
|
|
88
|
+
const parts = new Array(count);
|
|
89
|
+
const from = new Int32Array(count).fill(-1);
|
|
90
|
+
const weights = new Int32Array(count);
|
|
91
|
+
const claimed = new Uint8Array(oldParts.length);
|
|
92
|
+
const oldPositions = new Map();
|
|
93
|
+
const focused = focusedPosition(containerPart, oldParts);
|
|
94
|
+
for (let i = this._keys.length - 1; i >= 0; i--) {
|
|
95
|
+
oldPositions.set(this._keys[i], i);
|
|
96
|
+
}
|
|
97
|
+
for (let i = 0; i < count; i++) {
|
|
98
|
+
const position = oldPositions.get(keys[i]);
|
|
99
|
+
if (position !== undefined && !claimed[position]) {
|
|
100
|
+
claimed[position] = 1;
|
|
101
|
+
from[i] = position;
|
|
102
|
+
weights[i] = position === focused ? KEPT_WEIGHT * count : KEPT_WEIGHT;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
let spare = 0;
|
|
106
|
+
for (let i = 0; i < count; i++) {
|
|
107
|
+
if (from[i] < 0) {
|
|
108
|
+
while (claimed[spare])
|
|
109
|
+
spare++;
|
|
110
|
+
if (spare < oldParts.length) {
|
|
111
|
+
claimed[spare] = 1;
|
|
112
|
+
from[i] = spare;
|
|
113
|
+
weights[i] = 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
parts[i] = from[i] < 0 ? this._pool.pop() : oldParts[from[i]];
|
|
117
|
+
}
|
|
118
|
+
oldParts.forEach((part, position) => {
|
|
119
|
+
if (!claimed[position])
|
|
120
|
+
this._release(part);
|
|
121
|
+
});
|
|
122
|
+
const stable = heaviestIncreasingSubsequence(from, weights, oldParts.length);
|
|
123
|
+
let next;
|
|
124
|
+
for (let i = count - 1; i >= 0; i--) {
|
|
125
|
+
let part = parts[i];
|
|
126
|
+
if (!part) {
|
|
127
|
+
part = parts[i] = insertPart(containerPart, next);
|
|
128
|
+
}
|
|
129
|
+
else if (!stable[i]) {
|
|
130
|
+
insertPart(containerPart, next, part);
|
|
131
|
+
}
|
|
132
|
+
setChildPartValue(part, values[i]);
|
|
133
|
+
next = part;
|
|
134
|
+
}
|
|
135
|
+
while (this._pool.length > count) {
|
|
136
|
+
removeItemPart(this._pool.pop());
|
|
137
|
+
}
|
|
138
|
+
return parts;
|
|
139
|
+
}
|
|
140
|
+
_release(part) {
|
|
141
|
+
const doc = part.parentNode.ownerDocument;
|
|
142
|
+
if (this._poolRoot?.parentNode.ownerDocument !== doc) {
|
|
143
|
+
this._poolRoot = render(nothing, doc.createDocumentFragment(), {
|
|
144
|
+
isConnected: false,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
insertPart(this._poolRoot, undefined, part);
|
|
148
|
+
this._pool.push(part);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export const recycle = directive(RecycleDirective);
|
|
152
|
+
//# sourceMappingURL=recycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recycle.js","sourceRoot":"","sources":["../../../src/components/virtualization/recycle.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildPart, noChange, nothing, type RootPart, render } from 'lit';\nimport {\n clearPart,\n getCommittedValue,\n insertPart,\n setChildPartValue,\n setCommittedValue,\n} from 'lit/directive-helpers.js';\nimport { Directive, directive } from 'lit/directive.js';\nimport type { ItemTemplate, KeyFn } from 'lit/directives/repeat.js';\nimport { getRoot } from '#internals/utils/dom.js';\n\n/**\n * The weight of a kept part when the reconciliation selects the parts that do\n * not move. A recycled part weighs 1. A moved element needs a new style and\n * layout, but a recycled element needs a new layout for its new item anyway.\n * So on a scroll, the kept parts move only when they are fewer than half the\n * recycled parts.\n */\nconst KEPT_WEIGHT = 2;\n\n/**\n * Marks the entries of the increasing subsequence of `values` with the largest\n * total weight. The values are distinct integers in `[0, size)`, or negative\n * for the entries to skip. O(n log size).\n */\nfunction heaviestIncreasingSubsequence(\n values: Int32Array,\n weights: Int32Array,\n size: number\n): Uint8Array {\n // A Fenwick tree over the values. Each node holds the weight of the heaviest\n // subsequence that ends at a value in its range, and the entry of its last\n // value.\n const heaviest = new Int32Array(size + 1);\n const endsAt = new Int32Array(size + 1);\n const previous = new Int32Array(values.length);\n const marked = new Uint8Array(values.length);\n let best = 0;\n let last = -1;\n\n for (let i = 0; i < values.length; i++) {\n if (values[i] < 0) {\n continue;\n }\n\n let total = 0;\n let before = -1;\n for (let node = values[i]; node > 0; node -= node & -node) {\n if (heaviest[node] > total) {\n total = heaviest[node];\n before = endsAt[node];\n }\n }\n\n total += weights[i];\n previous[i] = before;\n for (let node = values[i] + 1; node <= size; node += node & -node) {\n if (total > heaviest[node]) {\n heaviest[node] = total;\n endsAt[node] = i;\n }\n }\n if (total > best) {\n best = total;\n last = i;\n }\n }\n\n for (let i = last; i >= 0; i = previous[i]) {\n marked[i] = 1;\n }\n return marked;\n}\n\n/**\n * Removes an item part, its content, and both markers. `removePart` leaves\n * the end marker in the DOM since lit-html 3.3.1 (lit/lit#5010).\n */\nfunction removeItemPart(part: ChildPart): void {\n clearPart(part);\n (part.startNode as ChildNode).remove();\n (part.endNode as ChildNode).remove();\n}\n\n/** Returns the position of the part in `parts` that holds the focus, or -1. */\nfunction focusedPosition(\n containerPart: ChildPart,\n parts: readonly ChildPart[]\n): number {\n const container = containerPart.parentNode;\n let node: Node | null = getRoot(container).activeElement;\n\n while (node && node.parentNode !== container) {\n node = node.parentNode;\n }\n if (!node) {\n return -1;\n }\n\n return parts.findIndex((part) => {\n let n = part.startNode!.nextSibling;\n while (n && n !== part.endNode && n !== node) {\n n = n.nextSibling;\n }\n return n === node;\n });\n}\n\nclass RecycleDirective extends Directive {\n /** The key of each committed item part, in DOM order. */\n private _keys: unknown[] = [];\n\n /** Item parts that no key needed, detached and kept for reuse. */\n private readonly _pool: ChildPart[] = [];\n\n /**\n * The disconnected parent of the pooled parts, in the document of the\n * container. A part that moves to another document is adopted: its custom\n * elements get `adoptedCallback`, and its images load again. `insertPart`\n * notifies the async directives in a part when it moves the part between\n * parents with a different connected state, so a pooled part is\n * disconnected, and a reused one is connected again.\n */\n private _poolRoot?: RootPart;\n\n public render<T>(\n items: readonly T[],\n _keyFn: KeyFn<T>,\n template: ItemTemplate<T>\n ): unknown[] {\n return items.map(template);\n }\n\n public override update<T>(\n containerPart: ChildPart,\n [items, keyFn, template]: [readonly T[], KeyFn<T>, ItemTemplate<T>]\n ): unknown {\n const keys = items.map(keyFn);\n const values = items.map(template);\n const committed = getCommittedValue(containerPart);\n\n // First render, or the part held another value: Lit creates the parts.\n if (!Array.isArray(committed)) {\n this._keys = keys;\n return values;\n }\n\n setCommittedValue(\n containerPart,\n this._reconcile(containerPart, committed as ChildPart[], keys, values)\n );\n this._keys = keys;\n return noChange;\n }\n\n /**\n * Gives each key an item part, puts the parts in key order, and sets their\n * values.\n *\n * 1. A key that stays keeps its part.\n * 2. The other keys take the parts of the keys that left, in DOM order, so\n * a full replacement moves no DOM. Then they take pooled parts. A part\n * is created only when both run out.\n * 3. The parts that no key takes go to the pool, so a window that changes\n * size by an item or two creates no DOM.\n * 4. The reused parts in the heaviest subsequence that keeps its old order\n * do not move, see `KEPT_WEIGHT`. A kept part that holds the focus\n * weighs more than all the other parts together, so it does not move and\n * keeps the focus. Each other part moves in front of its successor,\n * unless it is already there.\n */\n private _reconcile(\n containerPart: ChildPart,\n oldParts: ChildPart[],\n keys: unknown[],\n values: unknown[]\n ): ChildPart[] {\n const count = keys.length;\n const parts: (ChildPart | undefined)[] = new Array(count);\n // The old DOM position (-1 for a pooled or new part) and the weight of the\n // part at each new position.\n const from = new Int32Array(count).fill(-1);\n const weights = new Int32Array(count);\n const claimed = new Uint8Array(oldParts.length);\n const oldPositions = new Map<unknown, number>();\n const focused = focusedPosition(containerPart, oldParts);\n\n for (let i = this._keys.length - 1; i >= 0; i--) {\n oldPositions.set(this._keys[i], i);\n }\n\n for (let i = 0; i < count; i++) {\n const position = oldPositions.get(keys[i]);\n\n if (position !== undefined && !claimed[position]) {\n claimed[position] = 1;\n from[i] = position;\n weights[i] = position === focused ? KEPT_WEIGHT * count : KEPT_WEIGHT;\n }\n }\n\n let spare = 0;\n for (let i = 0; i < count; i++) {\n if (from[i] < 0) {\n while (claimed[spare]) spare++;\n if (spare < oldParts.length) {\n claimed[spare] = 1;\n from[i] = spare;\n weights[i] = 1;\n }\n }\n parts[i] = from[i] < 0 ? this._pool.pop() : oldParts[from[i]];\n }\n\n oldParts.forEach((part, position) => {\n if (!claimed[position]) this._release(part);\n });\n\n const stable = heaviestIncreasingSubsequence(\n from,\n weights,\n oldParts.length\n );\n\n let next: ChildPart | undefined;\n for (let i = count - 1; i >= 0; i--) {\n let part = parts[i];\n\n if (!part) {\n part = parts[i] = insertPart(containerPart, next);\n } else if (!stable[i]) {\n insertPart(containerPart, next, part);\n }\n\n setChildPartValue(part, values[i]);\n next = part;\n }\n\n // Cap the pool at the window size, so a window that shrinks for good\n // frees its parts.\n while (this._pool.length > count) {\n removeItemPart(this._pool.pop()!);\n }\n\n return parts as ChildPart[];\n }\n\n private _release(part: ChildPart): void {\n const doc = part.parentNode.ownerDocument!;\n\n // A new root on the first release, and after the container moves to\n // another document. The parts in an old root move to the new document\n // only when they are reused.\n if (this._poolRoot?.parentNode.ownerDocument !== doc) {\n this._poolRoot = render(nothing, doc.createDocumentFragment(), {\n isConnected: false,\n });\n }\n\n insertPart(this._poolRoot, undefined, part);\n this._pool.push(part);\n }\n}\n\ninterface RecycleDirectiveFn {\n <T>(items: readonly T[], keyFn: KeyFn<T>, template: ItemTemplate<T>): unknown;\n}\n\n/**\n * Renders `items` as `repeat` does, but gives the DOM of a key that leaves to\n * a key that arrives. `repeat` destroys the part of each key that leaves and\n * creates one for each key that arrives, which in a scrolling window is DOM\n * churn on each scroll step. A reused part keeps any DOM state that the\n * template does not bind.\n */\nexport const recycle = directive(RecycleDirective) as RecycleDirectiveFn;\n"]}
|
|
@@ -3,6 +3,7 @@ import type { Constructor } from '#internals/mixins/constructor.js';
|
|
|
3
3
|
import { VirtualScrollEngine } from './engine.js';
|
|
4
4
|
import { type VirtualScrollDataRequest, VirtualScrollItemContext, type VirtualScrollState } from './types.js';
|
|
5
5
|
export type VirtualScrollItemTemplate<T> = (context: VirtualScrollItemContext<T>) => TemplateResult | typeof nothing;
|
|
6
|
+
export type VirtualScrollKeyFunction<T> = (item: T, index: number) => unknown;
|
|
6
7
|
export interface IgcVirtualScrollComponentEventMap {
|
|
7
8
|
igcStateChange: CustomEvent<VirtualScrollState>;
|
|
8
9
|
igcDataRequest: CustomEvent<VirtualScrollDataRequest>;
|
|
@@ -32,10 +33,8 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
|
|
|
32
33
|
private readonly _itemResizeController;
|
|
33
34
|
private _currentRange;
|
|
34
35
|
/**
|
|
35
|
-
* The item index each wrapper element was last observed under.
|
|
36
|
-
*
|
|
37
|
-
* can host a different item at an identical size, and a ResizeObserver
|
|
38
|
-
* does not report that. See `_scheduleItemMeasurement`.
|
|
36
|
+
* The item index each wrapper element was last observed under. See
|
|
37
|
+
* `_scheduleItemMeasurement`.
|
|
39
38
|
*/
|
|
40
39
|
private readonly _observedItemIndexes;
|
|
41
40
|
private _lastEmittedState;
|
|
@@ -43,18 +42,18 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
|
|
|
43
42
|
private _layoutCompletePromise;
|
|
44
43
|
private _scrollRequestId;
|
|
45
44
|
/**
|
|
46
|
-
* The `startIndex` of the last
|
|
47
|
-
*
|
|
45
|
+
* The `startIndex` of the last `igcDataRequest`, which is also the item count
|
|
46
|
+
* at that emit. See `_checkDataRequest`.
|
|
48
47
|
*
|
|
49
|
-
* Kept across a disconnect,
|
|
50
|
-
*
|
|
51
|
-
* of the two
|
|
48
|
+
* Kept across a disconnect, as `_hasPendingDataRequest` is. A move in the DOM
|
|
49
|
+
* does not cancel what the consumer was already asked for, and clearing only
|
|
50
|
+
* one of the two opens the request loop again on reconnect.
|
|
52
51
|
*/
|
|
53
52
|
private _lastDataRequestIndex;
|
|
54
53
|
/**
|
|
55
|
-
* The live scroll offset on the active axis. Not reactive
|
|
56
|
-
*
|
|
57
|
-
*
|
|
54
|
+
* The live scroll offset on the active axis. Not reactive: `render` reads it
|
|
55
|
+
* only through `_currentRange`, so `_handleScroll` schedules an update only
|
|
56
|
+
* if the window moves.
|
|
58
57
|
*/
|
|
59
58
|
private _scrollPosition;
|
|
60
59
|
private _viewportSize;
|
|
@@ -82,6 +81,8 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
|
|
|
82
81
|
/**
|
|
83
82
|
* Estimated item size in pixels, used before an item is measured in the DOM.
|
|
84
83
|
* After the first render of an item, the engine replaces the estimate with the measured size.
|
|
84
|
+
* The average measured size also replaces the estimate of the items that are not measured
|
|
85
|
+
* yet, so the scrollbar follows the real content.
|
|
85
86
|
* @attr estimated-item-size
|
|
86
87
|
* @default 50
|
|
87
88
|
*/
|
|
@@ -98,16 +99,32 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
|
|
|
98
99
|
* infer an item's position from the markup. Templates that render a role
|
|
99
100
|
* with set semantics (`option`, `listitem`, `row`, ...) should map the
|
|
100
101
|
* context's `index` and `count` onto `aria-posinset` and `aria-setsize`.
|
|
102
|
+
*
|
|
103
|
+
* Item elements are recycled (see `keyFunction`), so DOM state that the
|
|
104
|
+
* template does not bind moves to another item, for example the state of a
|
|
105
|
+
* checkbox without a `checked` binding. Bind all item state. Lit compares a
|
|
106
|
+
* binding with the value that it set last, not with the element, so bind
|
|
107
|
+
* state that the user changes with Lit's `live` directive. Also write user
|
|
108
|
+
* changes back to the item, or they are lost when the item leaves the window.
|
|
109
|
+
* To get new DOM for each item, wrap the content in Lit's `keyed` directive
|
|
110
|
+
* with the item key: `` html`${keyed(ctx.value.id, content)}` ``.
|
|
101
111
|
*/
|
|
102
112
|
itemTemplate: VirtualScrollItemTemplate<T> | null;
|
|
113
|
+
/**
|
|
114
|
+
* A function that returns a unique key for an item. Receives the item and its index in `data`.
|
|
115
|
+
*
|
|
116
|
+
* An item keeps its rendered element while its key stays in the rendered window. The elements
|
|
117
|
+
* of keys that leave the window are reused for keys that enter it. Without it, the index is the
|
|
118
|
+
* key, so after a `data` change an index keeps its element and shows its new item. Set it when
|
|
119
|
+
* items move within `data`, for example on sort, insert or remove.
|
|
120
|
+
*/
|
|
121
|
+
keyFunction: VirtualScrollKeyFunction<T> | null;
|
|
103
122
|
private _adoptStyles;
|
|
104
123
|
constructor();
|
|
105
124
|
/** @internal */
|
|
106
125
|
createRenderRoot(): HTMLElement | DocumentFragment;
|
|
107
126
|
/** @internal */
|
|
108
127
|
connectedCallback(): void;
|
|
109
|
-
/** @internal */
|
|
110
|
-
disconnectedCallback(): void;
|
|
111
128
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
112
129
|
protected updated(_changed: PropertyValues<this>): void;
|
|
113
130
|
protected render(): TemplateResult;
|
|
@@ -118,18 +135,17 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
|
|
|
118
135
|
private get _normalizedItemSize();
|
|
119
136
|
/** `data`, guarded against a nullish value set by the consumer. */
|
|
120
137
|
private get _items();
|
|
138
|
+
/** The key that ties the item at `index` to its rendered element. */
|
|
139
|
+
private _keyOf;
|
|
121
140
|
/**
|
|
122
141
|
* The window to render for the current scroll position and viewport. Empty
|
|
123
142
|
* until an `itemTemplate` is set, because nothing renders without one.
|
|
124
143
|
*/
|
|
125
144
|
private _computeRange;
|
|
126
145
|
/**
|
|
127
|
-
* The scroll offset that aligns `index` in the viewport
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* For `block: 'nearest'` on an item already in view, returns the current
|
|
132
|
-
* offset, so no scroll occurs.
|
|
146
|
+
* The scroll offset that aligns `index` in the viewport, as `options` gives,
|
|
147
|
+
* from the current size data of the engine. The same input can give a
|
|
148
|
+
* different result as more items are measured.
|
|
133
149
|
*/
|
|
134
150
|
private _getAlignedScrollOffset;
|
|
135
151
|
/** Applies a scroll offset to the correct axis, accounting for RTL. */
|
|
@@ -137,84 +153,83 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
|
|
|
137
153
|
/** The current real scroll position on the active axis, normalized for RTL. */
|
|
138
154
|
private _currentAxisScroll;
|
|
139
155
|
/**
|
|
140
|
-
* Applies a scroll offset to the active axis and waits for the scroll
|
|
141
|
-
*
|
|
156
|
+
* Applies a scroll offset to the active axis, and waits for the scroll to
|
|
157
|
+
* settle.
|
|
142
158
|
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
159
|
+
* @remarks
|
|
160
|
+
* `scrollend` does not fire if the offset does not move the scroll position,
|
|
161
|
+
* so that case resolves immediately. The timeout covers an event that never
|
|
162
|
+
* arrives, for example when the element disconnects during the scroll.
|
|
147
163
|
*/
|
|
148
164
|
private _scrollAndWaitForEnd;
|
|
149
165
|
/**
|
|
150
|
-
* Resolves with `task
|
|
151
|
-
*
|
|
152
|
-
* listener remains.
|
|
166
|
+
* Resolves with `task`, or with a deadline of `ms`, whichever is first. The
|
|
167
|
+
* signal then stops the other, so no timer or listener stays alive.
|
|
153
168
|
*/
|
|
154
169
|
private _withDeadline;
|
|
155
170
|
private _waitForScrollEnd;
|
|
156
171
|
/**
|
|
157
|
-
* Resolves
|
|
158
|
-
* closest replacement for `scrollend`. The first timer starts immediately,
|
|
159
|
-
*
|
|
172
|
+
* Resolves if no `scroll` event arrives for `SCROLL_IDLE_MS`, which is the
|
|
173
|
+
* closest replacement for `scrollend`. The first timer starts immediately, so
|
|
174
|
+
* a scroll that does not move also settles.
|
|
160
175
|
*/
|
|
161
176
|
private _waitForScrollIdle;
|
|
162
177
|
private _timeout;
|
|
163
178
|
private _measureViewport;
|
|
164
179
|
/**
|
|
165
|
-
* Records the new scroll offset. Schedules a render only
|
|
180
|
+
* Records the new scroll offset. Schedules a render only if the rendered
|
|
166
181
|
* window moves.
|
|
167
182
|
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* one.
|
|
183
|
+
* @remarks
|
|
184
|
+
* `render` reads `_currentRange`, not the scroll offset. Without the guard,
|
|
185
|
+
* a scroll inside one item runs each item template again for the same
|
|
186
|
+
* result. `willUpdate` recomputes `_currentRange` for the other triggers,
|
|
187
|
+
* so this skips only the redundant passes.
|
|
174
188
|
*/
|
|
175
189
|
private _handleScroll;
|
|
176
190
|
/**
|
|
177
|
-
* The
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
191
|
+
* The length of the prefix that a `data` change keeps: the first index at
|
|
192
|
+
* which the old and the new items differ, or the length of the shorter array
|
|
193
|
+
* if neither differs. Measurements below that index stay valid. An append
|
|
194
|
+
* keeps all the previous items. A filter or a replacement keeps fewer.
|
|
195
|
+
*
|
|
196
|
+
* @remarks
|
|
197
|
+
* The test is item identity. An item that changes in place keeps its
|
|
198
|
+
* measured size.
|
|
182
199
|
*/
|
|
183
200
|
private _firstChangedIndex;
|
|
184
201
|
private _handleItemResize;
|
|
185
202
|
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* An `observe` call on an already observed element is a no-op, so a
|
|
189
|
-
* re-measurement on demand requires re-registration: unobserve, then
|
|
190
|
-
* observe.
|
|
203
|
+
* Syncs the item observer with the rendered window, and applies only the
|
|
204
|
+
* difference.
|
|
191
205
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
206
|
+
* @remarks
|
|
207
|
+
* `observe` on an already observed element does nothing, so a new
|
|
208
|
+
* measurement needs `unobserve` and then `observe`. Do this for each element
|
|
209
|
+
* whose `data-vs-index` changed. The wrapper elements are recycled, so after
|
|
210
|
+
* a scroll one element can hold a different item at the same size. The
|
|
211
|
+
* observer does not report that, and the new index keeps its estimated size.
|
|
197
212
|
*/
|
|
198
213
|
private _scheduleItemMeasurement;
|
|
199
214
|
/**
|
|
200
|
-
* Emits `igcStateChange`.
|
|
201
|
-
* last reported one, because measurement
|
|
202
|
-
* change.
|
|
215
|
+
* Emits `igcStateChange`. Does nothing if the window is empty or equal to
|
|
216
|
+
* the last reported one, because a measurement pass renders again with no
|
|
217
|
+
* window change.
|
|
203
218
|
*/
|
|
204
219
|
private _emitStateChange;
|
|
205
220
|
private _checkDataRequest;
|
|
206
221
|
/**
|
|
207
|
-
* Resolves on the next animation frame, or after `LAYOUT_FRAME_TIMEOUT_MS`
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
222
|
+
* Resolves on the next animation frame, or after `LAYOUT_FRAME_TIMEOUT_MS` if
|
|
223
|
+
* no frame arrives. A hidden tab or a disconnected element gets no frames,
|
|
224
|
+
* and `layoutComplete` must still settle. Such a state has no layout to wait
|
|
225
|
+
* for, so an early resolve is safe.
|
|
211
226
|
*/
|
|
212
227
|
private _nextFrame;
|
|
213
228
|
/**
|
|
214
|
-
* Waits for the current update, then lets ResizeObserver
|
|
215
|
-
* run.
|
|
216
|
-
*
|
|
217
|
-
*
|
|
229
|
+
* Waits for the current update, then lets the ResizeObserver measurements
|
|
230
|
+
* run. If those schedule one more render, for example when a measured size
|
|
231
|
+
* replaces an estimate, the wait repeats until nothing is pending, up to a
|
|
232
|
+
* safety cap.
|
|
218
233
|
*/
|
|
219
234
|
private _resolveLayoutComplete;
|
|
220
235
|
/**
|
|
@@ -230,6 +245,10 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
|
|
|
230
245
|
/**
|
|
231
246
|
* Scrolls to the specified item index.
|
|
232
247
|
*
|
|
248
|
+
* `block` (`inline` in the horizontal orientation) positions the item as in
|
|
249
|
+
* `scrollIntoView`, and defaults to `start`. With `nearest`, the item
|
|
250
|
+
* scrolls the smallest distance that brings it into view.
|
|
251
|
+
*
|
|
233
252
|
* Items outside the rendered window have only an estimated size, so the
|
|
234
253
|
* first jump can miss the target. The items at the landing point are then
|
|
235
254
|
* measured, and the scroll position is corrected. This repeats until the
|