@dataloop-ai/components 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/.eslintrc.js +154 -0
  2. package/.prettierrc.json +7 -0
  3. package/Dockerfile +12 -0
  4. package/LICENSE +201 -0
  5. package/README.md +43 -0
  6. package/favicon.ico +0 -0
  7. package/index.html +13 -0
  8. package/index.ts +1 -0
  9. package/jest.config.js +16 -0
  10. package/jest.setup.js +59 -0
  11. package/models.ts +1 -0
  12. package/package.json +109 -0
  13. package/src/App.vue +201 -0
  14. package/src/assets/globals.scss +253 -0
  15. package/src/assets/globalsKeys.ts +28 -0
  16. package/src/components/DlAccordion/AccordionHeader.vue +148 -0
  17. package/src/components/DlAccordion/DlAccordion.vue +108 -0
  18. package/src/components/DlAccordion/index.ts +2 -0
  19. package/src/components/DlAlert.vue +227 -0
  20. package/src/components/DlAvatar.vue +99 -0
  21. package/src/components/DlBadge.vue +127 -0
  22. package/src/components/DlButton/DlButton.vue +370 -0
  23. package/src/components/DlButton/index.ts +4 -0
  24. package/src/components/DlButton/utils.ts +169 -0
  25. package/src/components/DlButtonGroup.vue +122 -0
  26. package/src/components/DlCheckbox.vue +298 -0
  27. package/src/components/DlChip/DlChip.vue +244 -0
  28. package/src/components/DlChip/index.ts +4 -0
  29. package/src/components/DlChip/utils.ts +100 -0
  30. package/src/components/DlColorPicker/DlAlpha.vue +142 -0
  31. package/src/components/DlColorPicker/DlBox.vue +75 -0
  32. package/src/components/DlColorPicker/DlColorPicker.vue +306 -0
  33. package/src/components/DlColorPicker/DlColors.vue +139 -0
  34. package/src/components/DlColorPicker/DlHue.vue +135 -0
  35. package/src/components/DlColorPicker/DlPreview.vue +61 -0
  36. package/src/components/DlColorPicker/DlSaturation.vue +152 -0
  37. package/src/components/DlColorPicker/constants.ts +16 -0
  38. package/src/components/DlColorPicker/index.ts +20 -0
  39. package/src/components/DlColorPicker/types.ts +11 -0
  40. package/src/components/DlColorPicker/utils.ts +128 -0
  41. package/src/components/DlCounters.vue +173 -0
  42. package/src/components/DlDatePicker/DlCalendar.vue +332 -0
  43. package/src/components/DlDatePicker/DlDatePicker.vue +315 -0
  44. package/src/components/DlDatePicker/DlMonthCalendar.vue +282 -0
  45. package/src/components/DlDatePicker/classes/Calendar.ts +110 -0
  46. package/src/components/DlDatePicker/classes/CalendarDate.ts +12 -0
  47. package/src/components/DlDatePicker/classes/CustomDate.ts +218 -0
  48. package/src/components/DlDatePicker/index.ts +3 -0
  49. package/src/components/DlDatePicker/isInRange.ts +44 -0
  50. package/src/components/DlDatePicker/types.ts +4 -0
  51. package/src/components/DlDatePicker/utils.ts +39 -0
  52. package/src/components/DlDateTimeRange/DlCardSidebar.vue +109 -0
  53. package/src/components/DlDateTimeRange/DlDateInput.vue +105 -0
  54. package/src/components/DlDateTimeRange/DlDateTimeRange.vue +468 -0
  55. package/src/components/DlDateTimeRange/index.ts +3 -0
  56. package/src/components/DlDateTimeRange/types.ts +42 -0
  57. package/src/components/DlDialogBox/DlDialogBox.vue +196 -0
  58. package/src/components/DlDialogBox/DlDialogBoxFooter.vue +22 -0
  59. package/src/components/DlDialogBox/DlDialogBoxHeader.vue +75 -0
  60. package/src/components/DlDialogBox/index.ts +5 -0
  61. package/src/components/DlDropdownButton.vue +463 -0
  62. package/src/components/DlIcon.vue +147 -0
  63. package/src/components/DlInfoErrorMessage.vue +91 -0
  64. package/src/components/DlItem/DlItem.vue +35 -0
  65. package/src/components/DlItem/index.ts +2 -0
  66. package/src/components/DlItemSection.vue +88 -0
  67. package/src/components/DlLink/DlLink.vue +76 -0
  68. package/src/components/DlLink/index.ts +4 -0
  69. package/src/components/DlLink/utils.ts +4 -0
  70. package/src/components/DlList.vue +61 -0
  71. package/src/components/DlListItem/DlListItem.vue +205 -0
  72. package/src/components/DlListItem/index.ts +3 -0
  73. package/src/components/DlListItem/utils.ts +14 -0
  74. package/src/components/DlMenu/DlMenu.vue +438 -0
  75. package/src/components/DlMenu/index.ts +3 -0
  76. package/src/components/DlMenu/utils.ts +138 -0
  77. package/src/components/DlOptionGroup/DlOptionGroup.vue +201 -0
  78. package/src/components/DlOptionGroup/MenuItemWrapper.vue +48 -0
  79. package/src/components/DlOptionGroup/OptionGroup.types.ts +36 -0
  80. package/src/components/DlOptionGroup/SimpleWrapper.vue +28 -0
  81. package/src/components/DlOptionGroup/index.ts +4 -0
  82. package/src/components/DlOptionGroup/utils.ts +40 -0
  83. package/src/components/DlPagination/DlPagination.vue +184 -0
  84. package/src/components/DlPagination/PageNavigation.vue +350 -0
  85. package/src/components/DlPagination/PaginationLegend.vue +41 -0
  86. package/src/components/DlPagination/QuickNavigation.vue +146 -0
  87. package/src/components/DlPagination/RowsSelector.vue +74 -0
  88. package/src/components/DlPagination/index.ts +3 -0
  89. package/src/components/DlPanelContainer/DlPanel.vue +213 -0
  90. package/src/components/DlPanelContainer/DlPanelContainer.vue +527 -0
  91. package/src/components/DlPanelContainer/index.ts +4 -0
  92. package/src/components/DlPopup/DlPopup.vue +478 -0
  93. package/src/components/DlPopup/DraggableUpper.vue +64 -0
  94. package/src/components/DlPopup/PopupHeader.vue +129 -0
  95. package/src/components/DlPopup/index.ts +1 -0
  96. package/src/components/DlProgressBar.vue +159 -0
  97. package/src/components/DlProgressChart.vue +299 -0
  98. package/src/components/DlRadio.vue +218 -0
  99. package/src/components/DlRange/DlRange.vue +439 -0
  100. package/src/components/DlRange/utils.ts +209 -0
  101. package/src/components/DlSearch.vue +155 -0
  102. package/src/components/DlSelect/DlSelect.vue +992 -0
  103. package/src/components/DlSelect/SelectOption.vue +261 -0
  104. package/src/components/DlSelect/index.ts +4 -0
  105. package/src/components/DlSelect/utils.ts +43 -0
  106. package/src/components/DlSkeleton.vue +72 -0
  107. package/src/components/DlSlider/DlSlider.vue +243 -0
  108. package/src/components/DlSlider/components/DlSliderBase.vue +380 -0
  109. package/src/components/DlSlider/components/DlSliderInput.vue +123 -0
  110. package/src/components/DlSlider/components/index.ts +4 -0
  111. package/src/components/DlSlider/index.ts +3 -0
  112. package/src/components/DlSlider/sliderStyles.scss +109 -0
  113. package/src/components/DlSlider/useSlider.ts +277 -0
  114. package/src/components/DlSlider/utils.ts +7 -0
  115. package/src/components/DlSmartSearch/DlJsonEditor.vue +309 -0
  116. package/src/components/DlSmartSearch/DlSmartSearch.vue +333 -0
  117. package/src/components/DlSmartSearch/DlSmartSearchInput.vue +741 -0
  118. package/src/components/DlSmartSearch/DlSuggestionsDropdown.vue +73 -0
  119. package/src/components/DlSmartSearch/highlightSyntax.ts +169 -0
  120. package/src/components/DlSmartSearch/index.ts +4 -0
  121. package/src/components/DlSmartSearch/types.ts +36 -0
  122. package/src/components/DlSmartSearch/utils.ts +45 -0
  123. package/src/components/DlStepper/DlStepper.vue +196 -0
  124. package/src/components/DlStepper/DlStepperContainer.vue +55 -0
  125. package/src/components/DlStepper/DlStepperContent.vue +101 -0
  126. package/src/components/DlStepper/DlStepperFooter.vue +133 -0
  127. package/src/components/DlStepper/DlStepperHeader.vue +49 -0
  128. package/src/components/DlStepper/DlStepperSidebar.vue +167 -0
  129. package/src/components/DlStepper/Step.ts +101 -0
  130. package/src/components/DlStepper/Stepper.ts +107 -0
  131. package/src/components/DlStepper/index.ts +7 -0
  132. package/src/components/DlStepper/interfaces.ts +11 -0
  133. package/src/components/DlSwitch.vue +280 -0
  134. package/src/components/DlTabPanels/DlTabPanel.vue +22 -0
  135. package/src/components/DlTabPanels/DlTabPanels.vue +41 -0
  136. package/src/components/DlTabPanels/index.ts +4 -0
  137. package/src/components/DlTabPanels/utils.ts +19 -0
  138. package/src/components/DlTable/DlTable.vue +1264 -0
  139. package/src/components/DlTable/DlTd.vue +109 -0
  140. package/src/components/DlTable/DlTh.vue +126 -0
  141. package/src/components/DlTable/DlTr.vue +44 -0
  142. package/src/components/DlTable/ResizableManager.ts +233 -0
  143. package/src/components/DlTable/dl-table-styles.scss +466 -0
  144. package/src/components/DlTable/hooks/tableActions.ts +64 -0
  145. package/src/components/DlTable/hooks/tableColumnSelection.ts +112 -0
  146. package/src/components/DlTable/hooks/tableFilter.ts +42 -0
  147. package/src/components/DlTable/hooks/tablePagination.ts +197 -0
  148. package/src/components/DlTable/hooks/tableRowExpand.ts +55 -0
  149. package/src/components/DlTable/hooks/tableRowSelection.ts +106 -0
  150. package/src/components/DlTable/hooks/tableSort.ts +125 -0
  151. package/src/components/DlTable/index.ts +6 -0
  152. package/src/components/DlTable/types.ts +96 -0
  153. package/src/components/DlTabs/DlTab.vue +146 -0
  154. package/src/components/DlTabs/DlTabs.vue +192 -0
  155. package/src/components/DlTabs/TabsWrapper.vue +104 -0
  156. package/src/components/DlTabs/index.ts +4 -0
  157. package/src/components/DlTabs/types.ts +8 -0
  158. package/src/components/DlTextArea.vue +151 -0
  159. package/src/components/DlTextHolder.vue +65 -0
  160. package/src/components/DlTextInput.vue +753 -0
  161. package/src/components/DlThemeProvider.vue +41 -0
  162. package/src/components/DlTimePicker/DlTimeCounter.vue +81 -0
  163. package/src/components/DlTimePicker/DlTimePicker.vue +151 -0
  164. package/src/components/DlTimePicker/DlTimePickerInput.vue +311 -0
  165. package/src/components/DlTimePicker/index.ts +3 -0
  166. package/src/components/DlTimePicker/types.ts +4 -0
  167. package/src/components/DlTooltip.vue +456 -0
  168. package/src/components/DlTrend.vue +97 -0
  169. package/src/components/DlTypography.vue +87 -0
  170. package/src/components/DlVirtualScroll/DlVirtualScroll.vue +290 -0
  171. package/src/components/DlVirtualScroll/index.ts +3 -0
  172. package/src/components/DlVirtualScroll/useVirtualScroll.ts +833 -0
  173. package/src/components/DlWidget/DlWidget.vue +50 -0
  174. package/src/components/DlWidget/DlWidgetGrid.vue +360 -0
  175. package/src/components/DlWidget/index.ts +4 -0
  176. package/src/components/DlWidget/types.ts +6 -0
  177. package/src/components/DlWidget/utils.ts +30 -0
  178. package/src/components/index.ts +118 -0
  179. package/src/demo/DlAccordionDemo.vue +60 -0
  180. package/src/demo/DlAlertDemo.vue +54 -0
  181. package/src/demo/DlAvatarDemo.vue +43 -0
  182. package/src/demo/DlBadgeDemo.vue +65 -0
  183. package/src/demo/DlButtonDemo.vue +266 -0
  184. package/src/demo/DlCheckboxDemo.vue +50 -0
  185. package/src/demo/DlChipDemo.vue +181 -0
  186. package/src/demo/DlColorPickerDemo.vue +43 -0
  187. package/src/demo/DlCounterDemo.vue +53 -0
  188. package/src/demo/DlDateTimeRangeDemo.vue +217 -0
  189. package/src/demo/DlDialogBoxDemo.vue +175 -0
  190. package/src/demo/DlDropdownButtonDemo.vue +260 -0
  191. package/src/demo/DlIconDemo.vue +47 -0
  192. package/src/demo/DlLinkDemo.vue +23 -0
  193. package/src/demo/DlListDemo.vue +177 -0
  194. package/src/demo/DlMenuDemo.vue +524 -0
  195. package/src/demo/DlOptionGroupDemo.vue +79 -0
  196. package/src/demo/DlPaginationDemo.vue +44 -0
  197. package/src/demo/DlPanelContainerDemo.vue +221 -0
  198. package/src/demo/DlPopupDemo.vue +58 -0
  199. package/src/demo/DlProgressBarDemo.vue +22 -0
  200. package/src/demo/DlProgressChartDemo.vue +71 -0
  201. package/src/demo/DlRadioDemo.vue +35 -0
  202. package/src/demo/DlRangeDemo.vue +44 -0
  203. package/src/demo/DlSearchDemo.vue +27 -0
  204. package/src/demo/DlSelectDemo.vue +355 -0
  205. package/src/demo/DlSkeletonDemo.vue +20 -0
  206. package/src/demo/DlSliderDemo.vue +47 -0
  207. package/src/demo/DlStepperDemo/CenteredStepperInDialogBox.vue +260 -0
  208. package/src/demo/DlStepperDemo/SimpleStepper.vue +202 -0
  209. package/src/demo/DlStepperDemo/StepperInDialogBox.vue +261 -0
  210. package/src/demo/DlStepperDemo/index.ts +5 -0
  211. package/src/demo/DlStepperDemo/steps/AssignmentsStep.vue +97 -0
  212. package/src/demo/DlStepperDemo/steps/DataStep.vue +158 -0
  213. package/src/demo/DlStepperDemo/steps/GeneralStep.vue +106 -0
  214. package/src/demo/DlStepperDemo/steps/InstructionStep.vue +176 -0
  215. package/src/demo/DlStepperDemo/steps/QualityStep.vue +65 -0
  216. package/src/demo/DlSwitchDemo.vue +49 -0
  217. package/src/demo/DlTableDemo.vue +475 -0
  218. package/src/demo/DlTabsDemo.vue +67 -0
  219. package/src/demo/DlTdDemo.vue +19 -0
  220. package/src/demo/DlTextAreaDemo.vue +37 -0
  221. package/src/demo/DlTextHolderDemo.vue +42 -0
  222. package/src/demo/DlTextInputDemo.vue +89 -0
  223. package/src/demo/DlThDemo.vue +32 -0
  224. package/src/demo/DlTooltipDemo.vue +60 -0
  225. package/src/demo/DlTrDemo.vue +18 -0
  226. package/src/demo/DlTrendDemo.vue +25 -0
  227. package/src/demo/DlTypographyDemo.vue +93 -0
  228. package/src/demo/DlWidgetDemo.vue +157 -0
  229. package/src/demo/SmartSearchDemo/DlSmartSearchDemo.vue +202 -0
  230. package/src/demo/SmartSearchDemo/schema.ts +44 -0
  231. package/src/demo/index.ts +141 -0
  232. package/src/directives/TouchPan.ts +525 -0
  233. package/src/env.d.ts +8 -0
  234. package/src/hooks/use-anchor.ts +223 -0
  235. package/src/hooks/use-model-toggle.ts +181 -0
  236. package/src/hooks/use-portal.ts +104 -0
  237. package/src/hooks/use-scroll-target.ts +53 -0
  238. package/src/hooks/use-size-observer.ts +24 -0
  239. package/src/hooks/use-suggestions.ts +355 -0
  240. package/src/hooks/use-tick.ts +32 -0
  241. package/src/hooks/use-timeout.ts +20 -0
  242. package/src/hooks/use-transition.ts +32 -0
  243. package/src/hooks/use-window-size.ts +25 -0
  244. package/src/hooks/useForm.ts +12 -0
  245. package/src/index.ts +7 -0
  246. package/src/main.ts +4 -0
  247. package/src/models.ts +4 -0
  248. package/src/types.ts +6 -0
  249. package/src/utils/calcs.ts +18 -0
  250. package/src/utils/click-outside.ts +108 -0
  251. package/src/utils/component-name-parser.ts +1 -0
  252. package/src/utils/css-color-names.ts +150 -0
  253. package/src/utils/dom.ts +55 -0
  254. package/src/utils/draggable-table.ts +416 -0
  255. package/src/utils/escape-key.ts +54 -0
  256. package/src/utils/events.ts +67 -0
  257. package/src/utils/focus-manager.ts +33 -0
  258. package/src/utils/focusout.ts +29 -0
  259. package/src/utils/format.ts +3 -0
  260. package/src/utils/getColor.ts +17 -0
  261. package/src/utils/getLighterGradient.ts +36 -0
  262. package/src/utils/getRootStyles.ts +52 -0
  263. package/src/utils/global-config.ts +6 -0
  264. package/src/utils/global-nodes.ts +42 -0
  265. package/src/utils/includes.ts +3 -0
  266. package/src/utils/index.ts +29 -0
  267. package/src/utils/inject-object-prop.ts +21 -0
  268. package/src/utils/input-sizes.ts +7 -0
  269. package/src/utils/is-ellipsis-active.ts +3 -0
  270. package/src/utils/is-in-viewport.ts +13 -0
  271. package/src/utils/is.ts +15 -0
  272. package/src/utils/key-composition.ts +17 -0
  273. package/src/utils/keyCodes.ts +12 -0
  274. package/src/utils/logger/ConsoleLogger.ts +65 -0
  275. package/src/utils/logger/ILogger.ts +8 -0
  276. package/src/utils/logger/index.ts +8 -0
  277. package/src/utils/nav-keys-constants.ts +1 -0
  278. package/src/utils/portal.ts +55 -0
  279. package/src/utils/position-engine.ts +381 -0
  280. package/src/utils/render.ts +36 -0
  281. package/src/utils/ripple.ts +7 -0
  282. package/src/utils/scroll.ts +73 -0
  283. package/src/utils/selection.ts +15 -0
  284. package/src/utils/sort.ts +7 -0
  285. package/src/utils/splitByQuotes.ts +32 -0
  286. package/src/utils/string.ts +6 -0
  287. package/src/utils/teleport.ts +14 -0
  288. package/src/utils/theme.ts +2 -0
  289. package/src/utils/vm.ts +16 -0
  290. package/storybook.js +8 -0
  291. package/tsconfig.json +44 -0
  292. package/tsconfig.node.json +8 -0
  293. package/types.ts +1 -0
  294. package/vite.config.ts +13 -0
@@ -0,0 +1,833 @@
1
+ // The hook was created based on Quasar: https://github.com/quasarframework/quasar/blob/dev/ui/src/components/virtual-scroll/use-virtual-scroll.js
2
+
3
+ import { debounce } from 'lodash'
4
+ import {
5
+ ref,
6
+ computed,
7
+ watch,
8
+ onActivated,
9
+ onDeactivated,
10
+ onBeforeMount,
11
+ onBeforeUnmount,
12
+ nextTick,
13
+ getCurrentInstance,
14
+ ComputedRef,
15
+ Ref
16
+ } from 'vue-demi'
17
+
18
+ export interface ScrollDetails {
19
+ scrollStart: number
20
+ scrollViewSize: number
21
+ scrollMaxSize: number
22
+ offsetStart: number
23
+ offsetEnd: number
24
+ }
25
+
26
+ const aggBucketSize = 1000
27
+
28
+ const scrollToEdges = [
29
+ 'start',
30
+ 'center',
31
+ 'end',
32
+ 'start-force',
33
+ 'center-force',
34
+ 'end-force'
35
+ ]
36
+
37
+ const filterProto = Array.prototype.filter
38
+
39
+ const setOverflowAnchor =
40
+ window.getComputedStyle(document.body).overflowAnchor === void 0
41
+ ? () => {}
42
+ : function (contentEl: HTMLElement | null, index: number) {
43
+ if (contentEl === null) {
44
+ return
45
+ }
46
+
47
+ cancelAnimationFrame((contentEl as any)._dlOverflowAnimationFrame)
48
+ ;(contentEl as any)._dlOverflowAnimationFrame =
49
+ requestAnimationFrame(() => {
50
+ if (contentEl === null) {
51
+ return
52
+ }
53
+
54
+ const children = (contentEl.children ||
55
+ []) as HTMLCollection
56
+
57
+ const chilrensWithAnchor = filterProto.call(
58
+ children,
59
+ (el) => el.dataset && el.dataset.dlVsAnchor !== void 0
60
+ )
61
+
62
+ for (const element of chilrensWithAnchor) {
63
+ delete element.dataset.dlVsAnchor
64
+ }
65
+
66
+ const el = children[index] as HTMLElement
67
+
68
+ if (el && el.dataset) {
69
+ el.dataset.dlVsAnchor = ''
70
+ }
71
+ })
72
+ }
73
+
74
+ function sumFn(acc: number, h: number) {
75
+ return acc + h
76
+ }
77
+
78
+ function getScrollDetails(
79
+ parent: any,
80
+ child: any,
81
+ beforeRef: HTMLElement | null,
82
+ afterRef: HTMLElement | null,
83
+ stickyStart: number,
84
+ stickyEnd: number
85
+ ): ScrollDetails {
86
+ const parentCalc =
87
+ parent === window
88
+ ? document.scrollingElement || document.documentElement
89
+ : parent
90
+ const propElSize = 'offsetHeight'
91
+ const details = {
92
+ scrollStart: 0,
93
+ scrollViewSize: -stickyStart - stickyEnd,
94
+ scrollMaxSize: 0,
95
+ offsetStart: -stickyStart,
96
+ offsetEnd: -stickyEnd
97
+ }
98
+
99
+ if (parent === window) {
100
+ details.scrollStart =
101
+ window.pageYOffset || window.scrollY || document.body.scrollTop || 0
102
+ details.scrollViewSize += document.documentElement.clientHeight
103
+ } else {
104
+ details.scrollStart = parentCalc.scrollTop
105
+ details.scrollViewSize += parentCalc.clientHeight
106
+ }
107
+ details.scrollMaxSize = parentCalc.scrollHeight
108
+
109
+ if (beforeRef !== null) {
110
+ for (
111
+ let el = beforeRef.previousElementSibling;
112
+ el !== null;
113
+ el = el.previousElementSibling
114
+ ) {
115
+ if (el.classList.contains('dl-virtual-scroll--skip') === false) {
116
+ details.offsetStart += (el as HTMLElement)[propElSize]
117
+ }
118
+ }
119
+ }
120
+
121
+ if (afterRef !== null) {
122
+ for (
123
+ let el = afterRef.nextElementSibling;
124
+ el !== null;
125
+ el = el.nextElementSibling
126
+ ) {
127
+ if (el.classList.contains('dl-virtual-scroll--skip') === false) {
128
+ details.offsetEnd += (el as HTMLElement)[propElSize]
129
+ }
130
+ }
131
+ }
132
+
133
+ if (child !== parent) {
134
+ const parentRect = parentCalc.getBoundingClientRect()
135
+ const childRect = child.getBoundingClientRect()
136
+
137
+ details.offsetStart += childRect.top - parentRect.top
138
+ details.offsetEnd -= childRect.height
139
+
140
+ if (parent !== window) {
141
+ details.offsetStart += details.scrollStart
142
+ }
143
+ details.offsetEnd += details.scrollMaxSize - details.offsetStart
144
+ }
145
+
146
+ return details
147
+ }
148
+
149
+ function setScroll(parent: any, scroll: string | number) {
150
+ if (scroll === 'end') {
151
+ scroll = (parent === window ? document.body : parent)['scrollHeight']
152
+ }
153
+
154
+ if (parent === window) {
155
+ window.scrollTo(
156
+ window.pageXOffset ||
157
+ window.scrollX ||
158
+ document.body.scrollLeft ||
159
+ 0,
160
+ scroll as number
161
+ )
162
+ } else {
163
+ parent.scrollTop = scroll
164
+ }
165
+ }
166
+
167
+ function sumSize(sizeAgg: number[], size: number[], from: number, to: number) {
168
+ if (from >= to) {
169
+ return 0
170
+ }
171
+
172
+ const lastTo = size.length
173
+ const fromAgg = Math.floor(from / aggBucketSize)
174
+ const toAgg = Math.floor((to - 1) / aggBucketSize) + 1
175
+
176
+ let total = sizeAgg.slice(fromAgg, toAgg).reduce(sumFn, 0)
177
+
178
+ if (from % aggBucketSize !== 0) {
179
+ total -= size.slice(fromAgg * aggBucketSize, from).reduce(sumFn, 0)
180
+ }
181
+ if (to % aggBucketSize !== 0 && to !== lastTo) {
182
+ total -= size.slice(to, toAgg * aggBucketSize).reduce(sumFn, 0)
183
+ }
184
+
185
+ return total
186
+ }
187
+
188
+ export const commonVirtScrollProps = {
189
+ virtualScrollSliceSize: {
190
+ type: [Number, String],
191
+ default: null as number
192
+ },
193
+
194
+ virtualScrollSliceRatioBefore: {
195
+ type: [Number, String],
196
+ default: 1
197
+ },
198
+
199
+ virtualScrollSliceRatioAfter: {
200
+ type: [Number, String],
201
+ default: 1
202
+ },
203
+
204
+ virtualScrollItemSize: {
205
+ type: [Number, String],
206
+ default: 24
207
+ },
208
+
209
+ virtualScrollStickySizeStart: {
210
+ type: [Number, String],
211
+ default: 0
212
+ },
213
+
214
+ virtualScrollStickySizeEnd: {
215
+ type: [Number, String],
216
+ default: 0
217
+ },
218
+
219
+ tableColspan: [Number, String]
220
+ }
221
+
222
+ export const commonVirtPropsList = Object.keys(commonVirtScrollProps)
223
+
224
+ export const useVirtualScrollProps = {
225
+ onVirtualScroll: Function,
226
+ ...commonVirtScrollProps
227
+ }
228
+
229
+ export function useVirtualScroll({
230
+ virtualScrollLength,
231
+ getVirtualScrollTarget,
232
+ getVirtualScrollEl,
233
+ virtualScrollItemSizeComputed // optional
234
+ }: {
235
+ virtualScrollLength: ComputedRef<number>
236
+ getVirtualScrollTarget: () => HTMLElement | undefined
237
+ getVirtualScrollEl: () => HTMLElement
238
+ virtualScrollItemSizeComputed?: ComputedRef<number>
239
+ }) {
240
+ const vm = getCurrentInstance()
241
+
242
+ const { props, emit, proxy } = vm
243
+
244
+ let prevScrollStart: number | undefined
245
+ let prevToIndex: number
246
+ let localScrollViewSize: number | undefined
247
+ let virtualScrollSizesAgg: number[] = []
248
+ let virtualScrollSizes: number[]
249
+
250
+ const virtualScrollPaddingBefore: Ref<number> = ref(0)
251
+ const virtualScrollPaddingAfter: Ref<number> = ref(0)
252
+ const virtualScrollSliceSizeComputed: Ref<Record<string, any>> = ref({})
253
+
254
+ const beforeRef: Ref<HTMLElement | null> = ref(null)
255
+ const afterRef: Ref<HTMLElement | null> = ref(null)
256
+ const contentRef: Ref<HTMLElement | null> = ref(null)
257
+
258
+ const virtualScrollSliceRange = ref({ from: 0, to: 0 })
259
+
260
+ const colspanAttr = computed(() =>
261
+ props.tableColspan !== void 0 ? props.tableColspan : 100
262
+ ) as ComputedRef<number>
263
+
264
+ if (virtualScrollItemSizeComputed === void 0) {
265
+ virtualScrollItemSizeComputed = computed(
266
+ () => props.virtualScrollItemSize
267
+ ) as ComputedRef<number>
268
+ }
269
+
270
+ const needsReset = computed(() => virtualScrollItemSizeComputed!.value)
271
+
272
+ const needsSliceRecalc = computed(
273
+ () =>
274
+ needsReset.value +
275
+ ';' +
276
+ props.virtualScrollSliceRatioBefore +
277
+ ';' +
278
+ props.virtualScrollSliceRatioAfter
279
+ )
280
+
281
+ watch(needsSliceRecalc, () => {
282
+ setVirtualScrollSize()
283
+ })
284
+ watch(needsReset, reset)
285
+
286
+ function reset() {
287
+ localResetVirtualScroll(prevToIndex, true)
288
+ }
289
+
290
+ function refresh(toIndex: number) {
291
+ localResetVirtualScroll(toIndex === void 0 ? prevToIndex : toIndex)
292
+ }
293
+
294
+ function scrollTo(toIndex: number, edge?: string) {
295
+ const scrollEl = getVirtualScrollTarget()
296
+
297
+ if (
298
+ scrollEl === void 0 ||
299
+ scrollEl === null ||
300
+ scrollEl.nodeType === 8
301
+ ) {
302
+ return
303
+ }
304
+
305
+ const scrollDetails = getScrollDetails(
306
+ scrollEl,
307
+ getVirtualScrollEl(),
308
+ beforeRef.value,
309
+ afterRef.value,
310
+ props.virtualScrollStickySizeStart as number,
311
+ props.virtualScrollStickySizeEnd as number
312
+ )
313
+
314
+ if (localScrollViewSize !== scrollDetails.scrollViewSize) {
315
+ setVirtualScrollSize(scrollDetails.scrollViewSize)
316
+ }
317
+
318
+ setVirtualScrollSliceRange(
319
+ scrollEl,
320
+ scrollDetails,
321
+ Math.min(
322
+ virtualScrollLength.value - 1,
323
+ Math.max(0, parseInt(toIndex as any, 10) || 0)
324
+ ),
325
+ 0,
326
+ scrollToEdges.indexOf(edge!) > -1
327
+ ? edge
328
+ : prevToIndex > -1 && toIndex > prevToIndex
329
+ ? 'end'
330
+ : 'start'
331
+ )
332
+ }
333
+
334
+ function localOnVirtualScrollEvt() {
335
+ const scrollEl = getVirtualScrollTarget()
336
+
337
+ if (
338
+ scrollEl === void 0 ||
339
+ scrollEl === null ||
340
+ scrollEl.nodeType === 8
341
+ ) {
342
+ return
343
+ }
344
+
345
+ const scrollDetails = getScrollDetails(
346
+ scrollEl,
347
+ getVirtualScrollEl(),
348
+ beforeRef.value,
349
+ afterRef.value,
350
+ props.virtualScrollStickySizeStart as number,
351
+ props.virtualScrollStickySizeEnd as number
352
+ )
353
+ const listLastIndex = virtualScrollLength.value - 1
354
+ const listEndOffset =
355
+ scrollDetails.scrollMaxSize -
356
+ scrollDetails.offsetStart -
357
+ scrollDetails.offsetEnd -
358
+ virtualScrollPaddingAfter.value
359
+
360
+ if (prevScrollStart === scrollDetails.scrollStart) {
361
+ return
362
+ }
363
+
364
+ if (scrollDetails.scrollMaxSize <= 0) {
365
+ setVirtualScrollSliceRange(scrollEl, scrollDetails, 0, 0)
366
+ return
367
+ }
368
+
369
+ if (localScrollViewSize !== scrollDetails.scrollViewSize) {
370
+ setVirtualScrollSize(scrollDetails.scrollViewSize)
371
+ }
372
+
373
+ updateVirtualScrollSizes(virtualScrollSliceRange.value.from)
374
+
375
+ const scrollMaxStart = Math.floor(
376
+ scrollDetails.scrollMaxSize -
377
+ Math.max(
378
+ scrollDetails.scrollViewSize,
379
+ scrollDetails.offsetEnd
380
+ ) -
381
+ Math.min(
382
+ virtualScrollSizes[listLastIndex],
383
+ scrollDetails.scrollViewSize / 2
384
+ )
385
+ )
386
+
387
+ if (
388
+ scrollMaxStart > 0 &&
389
+ Math.ceil(scrollDetails.scrollStart) >= scrollMaxStart
390
+ ) {
391
+ setVirtualScrollSliceRange(
392
+ scrollEl,
393
+ scrollDetails,
394
+ listLastIndex,
395
+ scrollDetails.scrollMaxSize -
396
+ scrollDetails.offsetEnd -
397
+ virtualScrollSizesAgg.reduce(sumFn, 0)
398
+ )
399
+
400
+ return
401
+ }
402
+
403
+ let toIndex = 0
404
+ let listOffset = scrollDetails.scrollStart - scrollDetails.offsetStart
405
+ let offset = listOffset
406
+
407
+ if (
408
+ listOffset <= listEndOffset &&
409
+ listOffset + scrollDetails.scrollViewSize >=
410
+ virtualScrollPaddingBefore.value
411
+ ) {
412
+ listOffset -= virtualScrollPaddingBefore.value
413
+ toIndex = virtualScrollSliceRange.value.from
414
+ offset = listOffset
415
+ } else {
416
+ for (
417
+ let j = 0;
418
+ listOffset >= virtualScrollSizesAgg[j] &&
419
+ toIndex < listLastIndex;
420
+ j++
421
+ ) {
422
+ listOffset -= virtualScrollSizesAgg[j]
423
+ toIndex += aggBucketSize
424
+ }
425
+ }
426
+
427
+ while (listOffset > 0 && toIndex < listLastIndex) {
428
+ listOffset -= virtualScrollSizes[toIndex]
429
+ if (listOffset > -scrollDetails.scrollViewSize) {
430
+ toIndex++
431
+ offset = listOffset
432
+ } else {
433
+ offset = virtualScrollSizes[toIndex] + listOffset
434
+ }
435
+ }
436
+
437
+ setVirtualScrollSliceRange(scrollEl, scrollDetails, toIndex, offset)
438
+ }
439
+
440
+ function setVirtualScrollSliceRange(
441
+ scrollEl: HTMLElement,
442
+ scrollDetails: ScrollDetails,
443
+ toIndex: number,
444
+ offset: number,
445
+ align?: string
446
+ ) {
447
+ const alignForce =
448
+ typeof align === 'string' && align.indexOf('-force') > -1
449
+ const alignEnd =
450
+ alignForce === true ? align?.replace('-force', '') : align
451
+ const alignRange = alignEnd !== void 0 ? alignEnd : 'start'
452
+
453
+ let from = Math.max(
454
+ 0,
455
+ toIndex - virtualScrollSliceSizeComputed.value[alignRange]
456
+ )
457
+ let to = from + virtualScrollSliceSizeComputed.value.total
458
+
459
+ if (to > virtualScrollLength.value) {
460
+ to = virtualScrollLength.value
461
+ from = Math.max(0, to - virtualScrollSliceSizeComputed.value.total)
462
+ }
463
+
464
+ prevScrollStart = scrollDetails.scrollStart
465
+
466
+ const rangeChanged =
467
+ from !== virtualScrollSliceRange.value.from ||
468
+ to !== virtualScrollSliceRange.value.to
469
+
470
+ if (rangeChanged === false && alignEnd === void 0) {
471
+ emitScroll(toIndex)
472
+ return
473
+ }
474
+
475
+ const { activeElement } = document
476
+ const contentEl = contentRef.value
477
+ if (
478
+ rangeChanged === true &&
479
+ contentEl !== null &&
480
+ contentEl !== activeElement &&
481
+ contentEl.contains(activeElement) === true
482
+ ) {
483
+ contentEl.addEventListener('focusout', onBlurRefocusFn)
484
+
485
+ setTimeout(() => {
486
+ if (contentEl !== null) {
487
+ contentEl.removeEventListener('focusout', onBlurRefocusFn)
488
+ }
489
+ })
490
+ }
491
+
492
+ setOverflowAnchor(contentEl, toIndex - from)
493
+
494
+ const sizeBefore =
495
+ alignEnd !== void 0
496
+ ? virtualScrollSizes.slice(from, toIndex).reduce(sumFn, 0)
497
+ : 0
498
+
499
+ if (rangeChanged === true) {
500
+ // vue key matching algorithm works only if
501
+ // the array of VNodes changes on only one of the ends
502
+ // so we first change one end and then the other
503
+
504
+ const tempTo =
505
+ to >= virtualScrollSliceRange.value.from &&
506
+ from <= virtualScrollSliceRange.value.to
507
+ ? virtualScrollSliceRange.value.to
508
+ : to
509
+
510
+ virtualScrollSliceRange.value = { from, to: tempTo }
511
+ virtualScrollPaddingBefore.value = sumSize(
512
+ virtualScrollSizesAgg,
513
+ virtualScrollSizes,
514
+ 0,
515
+ from
516
+ )
517
+ virtualScrollPaddingAfter.value = sumSize(
518
+ virtualScrollSizesAgg,
519
+ virtualScrollSizes,
520
+ to,
521
+ virtualScrollLength.value
522
+ )
523
+
524
+ requestAnimationFrame(() => {
525
+ if (
526
+ virtualScrollSliceRange.value.to !== to &&
527
+ prevScrollStart === scrollDetails.scrollStart
528
+ ) {
529
+ virtualScrollSliceRange.value = {
530
+ from: virtualScrollSliceRange.value.from,
531
+ to
532
+ }
533
+ virtualScrollPaddingAfter.value = sumSize(
534
+ virtualScrollSizesAgg,
535
+ virtualScrollSizes,
536
+ to,
537
+ virtualScrollLength.value
538
+ )
539
+ }
540
+ })
541
+ }
542
+
543
+ requestAnimationFrame(() => {
544
+ // if the scroll was changed give up
545
+ // (another call to setVirtualScrollSliceRange before animation frame)
546
+ if (prevScrollStart !== scrollDetails.scrollStart) {
547
+ return
548
+ }
549
+
550
+ if (rangeChanged === true) {
551
+ updateVirtualScrollSizes(from)
552
+ }
553
+
554
+ const sizeAfter = virtualScrollSizes
555
+ .slice(from, toIndex)
556
+ .reduce(sumFn, 0)
557
+ const posStart =
558
+ sizeAfter +
559
+ scrollDetails.offsetStart +
560
+ virtualScrollPaddingBefore.value
561
+ const posEnd = posStart + virtualScrollSizes[toIndex]
562
+
563
+ let scrollPosition = posStart + offset
564
+
565
+ if (alignEnd !== void 0) {
566
+ const sizeDiff = sizeAfter - sizeBefore
567
+ const scrollStart = scrollDetails.scrollStart + sizeDiff
568
+
569
+ scrollPosition =
570
+ alignForce !== true &&
571
+ scrollStart < posStart &&
572
+ posEnd < scrollStart + scrollDetails.scrollViewSize
573
+ ? scrollStart
574
+ : alignEnd === 'end'
575
+ ? posEnd - scrollDetails.scrollViewSize
576
+ : posStart -
577
+ (alignEnd === 'start'
578
+ ? 0
579
+ : Math.round(
580
+ (scrollDetails.scrollViewSize -
581
+ virtualScrollSizes[toIndex]) /
582
+ 2
583
+ ))
584
+ }
585
+
586
+ prevScrollStart = scrollPosition
587
+
588
+ setScroll(scrollEl, scrollPosition)
589
+
590
+ emitScroll(toIndex)
591
+ })
592
+ }
593
+
594
+ function updateVirtualScrollSizes(from: number) {
595
+ const contentEl = contentRef.value
596
+
597
+ if (contentEl) {
598
+ const children = filterProto.call(
599
+ contentEl.children,
600
+ (el) =>
601
+ el.classList &&
602
+ el.classList.contains('dl-virtual-scroll--skip') === false
603
+ )
604
+ const childrenLength = children.length
605
+ const sizeFn = (el: HTMLElement) => el.offsetHeight
606
+
607
+ let index = from
608
+ let size
609
+ let diff
610
+
611
+ for (let i = 0; i < childrenLength; ) {
612
+ size = sizeFn(children[i])
613
+ i++
614
+
615
+ while (
616
+ i < childrenLength &&
617
+ children[i].classList.contains(
618
+ 'dl-virtual-scroll--with-prev'
619
+ ) === true
620
+ ) {
621
+ size += sizeFn(children[i])
622
+ i++
623
+ }
624
+
625
+ diff = size - virtualScrollSizes[index]
626
+
627
+ if (diff !== 0) {
628
+ virtualScrollSizes[index] += diff
629
+ virtualScrollSizesAgg[Math.floor(index / aggBucketSize)] +=
630
+ diff
631
+ }
632
+
633
+ index++
634
+ }
635
+ }
636
+ }
637
+
638
+ function onBlurRefocusFn() {
639
+ if (contentRef.value !== null && contentRef.value !== void 0) {
640
+ contentRef.value.focus()
641
+ }
642
+ }
643
+
644
+ function localResetVirtualScroll(toIndex?: number, fullReset?: boolean) {
645
+ const defaultSize = 1 * virtualScrollItemSizeComputed!.value
646
+
647
+ if (fullReset === true || Array.isArray(virtualScrollSizes) === false) {
648
+ virtualScrollSizes = []
649
+ }
650
+
651
+ const oldVirtualScrollSizesLength = virtualScrollSizes.length
652
+
653
+ virtualScrollSizes.length = virtualScrollLength.value
654
+
655
+ for (
656
+ let i = virtualScrollLength.value - 1;
657
+ i >= oldVirtualScrollSizesLength;
658
+ i--
659
+ ) {
660
+ virtualScrollSizes[i] = defaultSize
661
+ }
662
+
663
+ const jMax = Math.floor((virtualScrollLength.value - 1) / aggBucketSize)
664
+ virtualScrollSizesAgg = []
665
+ for (let j = 0; j <= jMax; j++) {
666
+ let size = 0
667
+ const iMax = Math.min(
668
+ (j + 1) * aggBucketSize,
669
+ virtualScrollLength.value
670
+ )
671
+ for (let i = j * aggBucketSize; i < iMax; i++) {
672
+ size += virtualScrollSizes[i]
673
+ }
674
+ virtualScrollSizesAgg.push(size)
675
+ }
676
+
677
+ prevToIndex = -1
678
+ prevScrollStart = void 0
679
+
680
+ virtualScrollPaddingBefore.value = sumSize(
681
+ virtualScrollSizesAgg,
682
+ virtualScrollSizes,
683
+ 0,
684
+ virtualScrollSliceRange.value.from
685
+ )
686
+ virtualScrollPaddingAfter.value = sumSize(
687
+ virtualScrollSizesAgg,
688
+ virtualScrollSizes,
689
+ virtualScrollSliceRange.value.to,
690
+ virtualScrollLength.value
691
+ )
692
+
693
+ if (toIndex && toIndex >= 0) {
694
+ updateVirtualScrollSizes(virtualScrollSliceRange.value.from)
695
+ nextTick(() => {
696
+ scrollTo(toIndex)
697
+ })
698
+ } else {
699
+ onVirtualScrollEvt()
700
+ }
701
+ }
702
+
703
+ function setVirtualScrollSize(scrollViewSize?: number) {
704
+ if (scrollViewSize === void 0 && typeof window !== 'undefined') {
705
+ const scrollEl = getVirtualScrollTarget()
706
+
707
+ if (
708
+ scrollEl !== void 0 &&
709
+ scrollEl !== null &&
710
+ scrollEl.nodeType !== 8
711
+ ) {
712
+ scrollViewSize = getScrollDetails(
713
+ scrollEl,
714
+ getVirtualScrollEl(),
715
+ beforeRef.value,
716
+ afterRef.value,
717
+ props.virtualScrollStickySizeStart as number,
718
+ props.virtualScrollStickySizeEnd as number
719
+ ).scrollViewSize
720
+ }
721
+ }
722
+
723
+ localScrollViewSize = scrollViewSize
724
+
725
+ const virtualScrollSliceRatioBefore =
726
+ parseFloat(props.virtualScrollSliceRatioBefore as string) || 0
727
+ const virtualScrollSliceRatioAfter =
728
+ parseFloat(props.virtualScrollSliceRatioAfter as string) || 0
729
+ const multiplier =
730
+ 1 + virtualScrollSliceRatioBefore + virtualScrollSliceRatioAfter
731
+ const view =
732
+ scrollViewSize === void 0 || scrollViewSize <= 0
733
+ ? 1
734
+ : Math.ceil(
735
+ scrollViewSize / virtualScrollItemSizeComputed!.value
736
+ )
737
+
738
+ const baseSize = Math.max(
739
+ 1,
740
+ view,
741
+ Math.ceil(
742
+ ((props.virtualScrollSliceSize as number) > 0
743
+ ? (props.virtualScrollSliceSize as number)
744
+ : 10) / multiplier
745
+ )
746
+ )
747
+
748
+ virtualScrollSliceSizeComputed.value = {
749
+ total: Math.ceil(baseSize * multiplier),
750
+ start: Math.ceil(baseSize * virtualScrollSliceRatioBefore),
751
+ center: Math.ceil(baseSize * (0.5 + virtualScrollSliceRatioBefore)),
752
+ end: Math.ceil(baseSize * (1 + virtualScrollSliceRatioBefore)),
753
+ view
754
+ }
755
+ }
756
+
757
+ function emitScroll(index: number) {
758
+ if (prevToIndex !== index) {
759
+ if (props.onVirtualScroll !== void 0) {
760
+ emit('virtual-scroll', {
761
+ index,
762
+ from: virtualScrollSliceRange.value.from,
763
+ to: virtualScrollSliceRange.value.to - 1,
764
+ direction: index < prevToIndex ? 'decrease' : 'increase',
765
+ ref: proxy
766
+ })
767
+ }
768
+
769
+ prevToIndex = index
770
+ }
771
+ }
772
+
773
+ setVirtualScrollSize()
774
+ const onVirtualScrollEvt = debounce(localOnVirtualScrollEvt, 35)
775
+
776
+ onBeforeMount(() => {
777
+ setVirtualScrollSize()
778
+ })
779
+
780
+ let shouldActivate = false
781
+
782
+ onDeactivated(() => {
783
+ shouldActivate = true
784
+ })
785
+
786
+ onActivated(() => {
787
+ if (shouldActivate !== true) {
788
+ return
789
+ }
790
+
791
+ const scrollEl = getVirtualScrollTarget()
792
+
793
+ if (
794
+ prevScrollStart !== void 0 &&
795
+ scrollEl !== void 0 &&
796
+ scrollEl !== null &&
797
+ scrollEl.nodeType !== 8
798
+ ) {
799
+ setScroll(scrollEl, prevScrollStart)
800
+ } else {
801
+ scrollTo(prevToIndex)
802
+ }
803
+ })
804
+
805
+ onBeforeUnmount(() => {
806
+ onVirtualScrollEvt.cancel()
807
+ })
808
+
809
+ // expose public methods
810
+ Object.assign(proxy, { scrollTo, reset, refresh })
811
+
812
+ return {
813
+ virtualScrollSliceRange,
814
+ virtualScrollSliceSizeComputed,
815
+
816
+ setVirtualScrollSize,
817
+ onVirtualScrollEvt,
818
+ localResetVirtualScroll,
819
+
820
+ scrollTo,
821
+ reset,
822
+ refresh,
823
+
824
+ virtualScrollPaddingBefore,
825
+ virtualScrollPaddingAfter,
826
+
827
+ beforeRef,
828
+ afterRef,
829
+ contentRef,
830
+
831
+ colspanAttr
832
+ }
833
+ }