@codeleap/web 7.0.2 → 7.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/dist/components/ActivityIndicator/index.js +16 -34
  2. package/dist/components/ActivityIndicator/index.js.map +1 -1
  3. package/dist/components/ActivityIndicator/styles.js +1 -2
  4. package/dist/components/ActivityIndicator/types.js +1 -2
  5. package/dist/components/Badge/index.js +24 -42
  6. package/dist/components/Badge/index.js.map +1 -1
  7. package/dist/components/Badge/styles.js +1 -2
  8. package/dist/components/Badge/types.js +1 -2
  9. package/dist/components/Button/index.js +19 -36
  10. package/dist/components/Button/index.js.map +1 -1
  11. package/dist/components/Button/styles.js +1 -2
  12. package/dist/components/Button/types.js +1 -2
  13. package/dist/components/Calendar/index.js +12 -29
  14. package/dist/components/Calendar/index.js.map +1 -1
  15. package/dist/components/Calendar/styles.js +1 -2
  16. package/dist/components/Calendar/types.js +1 -2
  17. package/dist/components/Carousel/index.js +40 -82
  18. package/dist/components/Carousel/index.js.map +1 -1
  19. package/dist/components/Carousel/styles.js +1 -2
  20. package/dist/components/Carousel/types.js +1 -2
  21. package/dist/components/Checkbox/index.js +24 -42
  22. package/dist/components/Checkbox/index.js.map +1 -1
  23. package/dist/components/Checkbox/styles.js +1 -2
  24. package/dist/components/Checkbox/types.js +1 -2
  25. package/dist/components/Collapse/index.js +17 -35
  26. package/dist/components/Collapse/index.js.map +1 -1
  27. package/dist/components/Collapse/styles.js +1 -2
  28. package/dist/components/Collapse/types.js +1 -2
  29. package/dist/components/ColorPicker/index.js +33 -51
  30. package/dist/components/ColorPicker/index.js.map +1 -1
  31. package/dist/components/ColorPicker/styles.js +1 -2
  32. package/dist/components/ColorPicker/types.js +1 -2
  33. package/dist/components/CropPicker/hooks.d.ts +2 -2
  34. package/dist/components/CropPicker/hooks.js +17 -20
  35. package/dist/components/CropPicker/hooks.js.map +1 -1
  36. package/dist/components/CropPicker/index.js +22 -40
  37. package/dist/components/CropPicker/index.js.map +1 -1
  38. package/dist/components/CropPicker/styles.js +1 -2
  39. package/dist/components/CropPicker/types.js +1 -2
  40. package/dist/components/CropPicker/utils.js +3 -9
  41. package/dist/components/CropPicker/utils.js.map +1 -1
  42. package/dist/components/DatePicker/index.js +23 -40
  43. package/dist/components/DatePicker/index.js.map +1 -1
  44. package/dist/components/DatePicker/styles.js +1 -2
  45. package/dist/components/DatePicker/types.js +1 -2
  46. package/dist/components/Drawer/index.js +22 -40
  47. package/dist/components/Drawer/index.js.map +1 -1
  48. package/dist/components/Drawer/styles.js +1 -2
  49. package/dist/components/Drawer/types.js +1 -2
  50. package/dist/components/Dropzone/context.js +11 -16
  51. package/dist/components/Dropzone/context.js.map +1 -1
  52. package/dist/components/Dropzone/elements.js +13 -19
  53. package/dist/components/Dropzone/elements.js.map +1 -1
  54. package/dist/components/Dropzone/index.js +35 -53
  55. package/dist/components/Dropzone/index.js.map +1 -1
  56. package/dist/components/Dropzone/styles.js +1 -2
  57. package/dist/components/Dropzone/types.js +1 -2
  58. package/dist/components/Dropzone/useDropzone.js +3 -6
  59. package/dist/components/Dropzone/useDropzone.js.map +1 -1
  60. package/dist/components/EmptyPlaceholder/index.js +40 -61
  61. package/dist/components/EmptyPlaceholder/index.js.map +1 -1
  62. package/dist/components/EmptyPlaceholder/styles.js +1 -2
  63. package/dist/components/EmptyPlaceholder/types.js +1 -2
  64. package/dist/components/Field/context.js +11 -17
  65. package/dist/components/Field/context.js.map +1 -1
  66. package/dist/components/Field/elements.js +31 -39
  67. package/dist/components/Field/elements.js.map +1 -1
  68. package/dist/components/Field/index.js +23 -41
  69. package/dist/components/Field/index.js.map +1 -1
  70. package/dist/components/Field/styles.js +1 -2
  71. package/dist/components/Field/types.js +1 -2
  72. package/dist/components/Field/useFieldInput.d.ts +1 -1
  73. package/dist/components/Field/useFieldInput.js +8 -11
  74. package/dist/components/Field/useFieldInput.js.map +1 -1
  75. package/dist/components/FileInput/index.js +14 -32
  76. package/dist/components/FileInput/index.js.map +1 -1
  77. package/dist/components/FileInput/types.js +1 -2
  78. package/dist/components/Icon/index.js +26 -44
  79. package/dist/components/Icon/index.js.map +1 -1
  80. package/dist/components/Icon/styles.js +1 -2
  81. package/dist/components/Icon/types.js +1 -2
  82. package/dist/components/List/context.js +20 -25
  83. package/dist/components/List/context.js.map +1 -1
  84. package/dist/components/List/elements.d.ts.map +1 -1
  85. package/dist/components/List/elements.js +58 -82
  86. package/dist/components/List/elements.js.map +1 -1
  87. package/dist/components/List/index.d.ts.map +1 -1
  88. package/dist/components/List/index.js +19 -36
  89. package/dist/components/List/index.js.map +1 -1
  90. package/dist/components/List/scroll.d.ts.map +1 -1
  91. package/dist/components/List/scroll.js +20 -20
  92. package/dist/components/List/scroll.js.map +1 -1
  93. package/dist/components/List/styles.js +1 -2
  94. package/dist/components/List/types.d.ts +13 -4
  95. package/dist/components/List/types.d.ts.map +1 -1
  96. package/dist/components/List/types.js +1 -2
  97. package/dist/components/List/useScrollEdgeDetection.d.ts +12 -0
  98. package/dist/components/List/useScrollEdgeDetection.d.ts.map +1 -0
  99. package/dist/components/List/useScrollEdgeDetection.js +37 -0
  100. package/dist/components/List/useScrollEdgeDetection.js.map +1 -0
  101. package/dist/components/LoadingOverlay/index.js +20 -38
  102. package/dist/components/LoadingOverlay/index.js.map +1 -1
  103. package/dist/components/LoadingOverlay/styles.js +1 -2
  104. package/dist/components/LoadingOverlay/types.js +1 -2
  105. package/dist/components/MaskedTextInput/index.js +14 -32
  106. package/dist/components/MaskedTextInput/index.js.map +1 -1
  107. package/dist/components/MaskedTextInput/mask.js +1 -4
  108. package/dist/components/MaskedTextInput/mask.js.map +1 -1
  109. package/dist/components/MaskedTextInput/types.js +1 -2
  110. package/dist/components/Modal/context.js +9 -14
  111. package/dist/components/Modal/context.js.map +1 -1
  112. package/dist/components/Modal/elements.js +23 -31
  113. package/dist/components/Modal/elements.js.map +1 -1
  114. package/dist/components/Modal/index.js +22 -40
  115. package/dist/components/Modal/index.js.map +1 -1
  116. package/dist/components/Modal/styles.js +1 -2
  117. package/dist/components/Modal/types.js +1 -2
  118. package/dist/components/NumberIncrement/index.js +29 -47
  119. package/dist/components/NumberIncrement/index.js.map +1 -1
  120. package/dist/components/NumberIncrement/styles.js +1 -2
  121. package/dist/components/NumberIncrement/types.js +1 -2
  122. package/dist/components/NumberIncrement/useNumberIncrement.js +21 -24
  123. package/dist/components/NumberIncrement/useNumberIncrement.js.map +1 -1
  124. package/dist/components/Overlay/index.js +21 -39
  125. package/dist/components/Overlay/index.js.map +1 -1
  126. package/dist/components/Overlay/styles.js +1 -2
  127. package/dist/components/Overlay/types.js +1 -2
  128. package/dist/components/PaginationButtons/index.js +26 -44
  129. package/dist/components/PaginationButtons/index.js.map +1 -1
  130. package/dist/components/PaginationButtons/styles.js +1 -2
  131. package/dist/components/PaginationButtons/types.js +1 -2
  132. package/dist/components/PaginationIndicator/ImperativePaginationIndicator.d.ts +13 -0
  133. package/dist/components/PaginationIndicator/ImperativePaginationIndicator.d.ts.map +1 -0
  134. package/dist/components/PaginationIndicator/ImperativePaginationIndicator.js +20 -0
  135. package/dist/components/PaginationIndicator/ImperativePaginationIndicator.js.map +1 -0
  136. package/dist/components/PaginationIndicator/index.d.ts +1 -0
  137. package/dist/components/PaginationIndicator/index.d.ts.map +1 -1
  138. package/dist/components/PaginationIndicator/index.js +25 -42
  139. package/dist/components/PaginationIndicator/index.js.map +1 -1
  140. package/dist/components/PaginationIndicator/styles.js +1 -2
  141. package/dist/components/PaginationIndicator/types.d.ts +9 -0
  142. package/dist/components/PaginationIndicator/types.d.ts.map +1 -1
  143. package/dist/components/PaginationIndicator/types.js +1 -2
  144. package/dist/components/Progress/Bar/Segmented.js +19 -23
  145. package/dist/components/Progress/Bar/Segmented.js.map +1 -1
  146. package/dist/components/Progress/Bar/index.js +29 -47
  147. package/dist/components/Progress/Bar/index.js.map +1 -1
  148. package/dist/components/Progress/Bar/styles.js +1 -2
  149. package/dist/components/Progress/Bar/types.js +1 -2
  150. package/dist/components/Progress/Circle/Segmented.js +22 -26
  151. package/dist/components/Progress/Circle/Segmented.js.map +1 -1
  152. package/dist/components/Progress/Circle/index.js +30 -48
  153. package/dist/components/Progress/Circle/index.js.map +1 -1
  154. package/dist/components/Progress/Circle/styles.js +1 -2
  155. package/dist/components/Progress/Circle/types.js +1 -2
  156. package/dist/components/Progress/index.js +2 -18
  157. package/dist/components/Progress/index.js.map +1 -1
  158. package/dist/components/Progress/utils.js +1 -4
  159. package/dist/components/Progress/utils.js.map +1 -1
  160. package/dist/components/RadioInput/index.js +26 -47
  161. package/dist/components/RadioInput/index.js.map +1 -1
  162. package/dist/components/RadioInput/styles.js +1 -2
  163. package/dist/components/RadioInput/types.js +1 -2
  164. package/dist/components/SearchInput/index.js +14 -51
  165. package/dist/components/SearchInput/index.js.map +1 -1
  166. package/dist/components/SectionFilters/index.js +38 -56
  167. package/dist/components/SectionFilters/index.js.map +1 -1
  168. package/dist/components/SectionFilters/styles.js +1 -2
  169. package/dist/components/SectionFilters/types.js +1 -2
  170. package/dist/components/Select/context.js +44 -50
  171. package/dist/components/Select/context.js.map +1 -1
  172. package/dist/components/Select/elements.js +23 -29
  173. package/dist/components/Select/elements.js.map +1 -1
  174. package/dist/components/Select/index.js +24 -41
  175. package/dist/components/Select/index.js.map +1 -1
  176. package/dist/components/Select/styles.js +1 -2
  177. package/dist/components/Select/types.js +1 -2
  178. package/dist/components/Select/useTriggerWidth.js +6 -9
  179. package/dist/components/Select/useTriggerWidth.js.map +1 -1
  180. package/dist/components/Slider/index.js +47 -68
  181. package/dist/components/Slider/index.js.map +1 -1
  182. package/dist/components/Slider/styles.js +1 -2
  183. package/dist/components/Slider/types.js +1 -2
  184. package/dist/components/Switch/index.js +22 -40
  185. package/dist/components/Switch/index.js.map +1 -1
  186. package/dist/components/Switch/styles.js +1 -2
  187. package/dist/components/Switch/types.js +1 -2
  188. package/dist/components/Tag/index.js +34 -55
  189. package/dist/components/Tag/index.js.map +1 -1
  190. package/dist/components/Tag/styles.js +1 -2
  191. package/dist/components/Tag/types.js +1 -2
  192. package/dist/components/Text/index.js +27 -48
  193. package/dist/components/Text/index.js.map +1 -1
  194. package/dist/components/Text/styles.js +1 -2
  195. package/dist/components/Text/types.js +1 -2
  196. package/dist/components/TextEditor/index.js +29 -50
  197. package/dist/components/TextEditor/index.js.map +1 -1
  198. package/dist/components/TextEditor/styles.js +1 -2
  199. package/dist/components/TextEditor/types.js +1 -2
  200. package/dist/components/TextInput/index.js +28 -49
  201. package/dist/components/TextInput/index.js.map +1 -1
  202. package/dist/components/TextInput/styles.js +1 -2
  203. package/dist/components/TextInput/types.js +1 -2
  204. package/dist/components/TextInput/useTextInput.d.ts +2 -2
  205. package/dist/components/TextInput/useTextInput.js +12 -15
  206. package/dist/components/TextInput/useTextInput.js.map +1 -1
  207. package/dist/components/Tooltip/index.js +33 -54
  208. package/dist/components/Tooltip/index.js.map +1 -1
  209. package/dist/components/Tooltip/styles.js +1 -2
  210. package/dist/components/Tooltip/types.js +1 -2
  211. package/dist/components/Touchable/index.js +23 -42
  212. package/dist/components/Touchable/index.js.map +1 -1
  213. package/dist/components/Touchable/styles.js +1 -2
  214. package/dist/components/Touchable/types.js +1 -2
  215. package/dist/components/View/index.js +15 -32
  216. package/dist/components/View/index.js.map +1 -1
  217. package/dist/components/View/styles.js +1 -2
  218. package/dist/components/View/types.js +1 -2
  219. package/dist/components/components.js +41 -57
  220. package/dist/components/components.js.map +1 -1
  221. package/dist/index.js +4 -20
  222. package/dist/index.js.map +1 -1
  223. package/dist/lib/ListMasonry.js +22 -31
  224. package/dist/lib/ListMasonry.js.map +1 -1
  225. package/dist/lib/ThemeVariables.js +6 -11
  226. package/dist/lib/ThemeVariables.js.map +1 -1
  227. package/dist/lib/WebStyleRegistry.js +3 -7
  228. package/dist/lib/WebStyleRegistry.js.map +1 -1
  229. package/dist/lib/hooks/index.js +22 -38
  230. package/dist/lib/hooks/index.js.map +1 -1
  231. package/dist/lib/hooks/useAnimatedStyle.js +5 -9
  232. package/dist/lib/hooks/useAnimatedStyle.js.map +1 -1
  233. package/dist/lib/hooks/useAnimatedVariantStyles.js +6 -9
  234. package/dist/lib/hooks/useAnimatedVariantStyles.js.map +1 -1
  235. package/dist/lib/hooks/useAsyncSelect.js +8 -11
  236. package/dist/lib/hooks/useAsyncSelect.js.map +1 -1
  237. package/dist/lib/hooks/useBreakpointMatch.js +19 -22
  238. package/dist/lib/hooks/useBreakpointMatch.js.map +1 -1
  239. package/dist/lib/hooks/useClick.js +7 -10
  240. package/dist/lib/hooks/useClick.js.map +1 -1
  241. package/dist/lib/hooks/useClickOutside.js +4 -7
  242. package/dist/lib/hooks/useClickOutside.js.map +1 -1
  243. package/dist/lib/hooks/useFileInput.js +3 -7
  244. package/dist/lib/hooks/useFileInput.js.map +1 -1
  245. package/dist/lib/hooks/useIsomorphicEffect.js +2 -5
  246. package/dist/lib/hooks/useIsomorphicEffect.js.map +1 -1
  247. package/dist/lib/hooks/useKeydown.js +9 -13
  248. package/dist/lib/hooks/useKeydown.js.map +1 -1
  249. package/dist/lib/hooks/useListFocus.js +4 -7
  250. package/dist/lib/hooks/useListFocus.js.map +1 -1
  251. package/dist/lib/hooks/useMediaQuery.js +8 -11
  252. package/dist/lib/hooks/useMediaQuery.js.map +1 -1
  253. package/dist/lib/hooks/usePageExitBlocker.js +6 -10
  254. package/dist/lib/hooks/usePageExitBlocker.js.map +1 -1
  255. package/dist/lib/hooks/usePagination.js +10 -13
  256. package/dist/lib/hooks/usePagination.js.map +1 -1
  257. package/dist/lib/hooks/usePopState.js +5 -9
  258. package/dist/lib/hooks/usePopState.js.map +1 -1
  259. package/dist/lib/hooks/usePopoverDismiss.js +5 -8
  260. package/dist/lib/hooks/usePopoverDismiss.js.map +1 -1
  261. package/dist/lib/hooks/useRefresh.js +9 -16
  262. package/dist/lib/hooks/useRefresh.js.map +1 -1
  263. package/dist/lib/hooks/useScrollEffect.js +3 -6
  264. package/dist/lib/hooks/useScrollEffect.js.map +1 -1
  265. package/dist/lib/hooks/useSearchParams.js +7 -10
  266. package/dist/lib/hooks/useSearchParams.js.map +1 -1
  267. package/dist/lib/hooks/useStaticAnimationStyles.js +3 -6
  268. package/dist/lib/hooks/useStaticAnimationStyles.js.map +1 -1
  269. package/dist/lib/hooks/useStylesFor.js +9 -13
  270. package/dist/lib/hooks/useStylesFor.js.map +1 -1
  271. package/dist/lib/hooks/useTouchableEvents.js +4 -7
  272. package/dist/lib/hooks/useTouchableEvents.js.map +1 -1
  273. package/dist/lib/hooks/useWindowFocus.js +7 -11
  274. package/dist/lib/hooks/useWindowFocus.js.map +1 -1
  275. package/dist/lib/hooks/useWindowSize.js +7 -10
  276. package/dist/lib/hooks/useWindowSize.js.map +1 -1
  277. package/dist/lib/index.js +6 -22
  278. package/dist/lib/index.js.map +1 -1
  279. package/dist/lib/tools/index.js +3 -19
  280. package/dist/lib/tools/index.js.map +1 -1
  281. package/dist/lib/tools/localStorage.js +8 -12
  282. package/dist/lib/tools/localStorage.js.map +1 -1
  283. package/dist/lib/tools/mediaQuery.js +3 -8
  284. package/dist/lib/tools/mediaQuery.js.map +1 -1
  285. package/dist/lib/tools/modal.js +13 -18
  286. package/dist/lib/tools/modal.js.map +1 -1
  287. package/dist/lib/utils/attributes.js +3 -6
  288. package/dist/lib/utils/attributes.js.map +1 -1
  289. package/dist/lib/utils/cache.d.ts +2 -2
  290. package/dist/lib/utils/cache.js +4 -11
  291. package/dist/lib/utils/cache.js.map +1 -1
  292. package/dist/lib/utils/index.js +5 -21
  293. package/dist/lib/utils/index.js.map +1 -1
  294. package/dist/lib/utils/pollyfils/scroll.js +1 -5
  295. package/dist/lib/utils/pollyfils/scroll.js.map +1 -1
  296. package/dist/lib/utils/stopPropagation.js +1 -4
  297. package/dist/lib/utils/stopPropagation.js.map +1 -1
  298. package/dist/lib/utils/test.js +3 -7
  299. package/dist/lib/utils/test.js.map +1 -1
  300. package/dist/types/index.js +1 -17
  301. package/dist/types/index.js.map +1 -1
  302. package/dist/types/utility.js +1 -2
  303. package/package.json +17 -17
  304. package/src/components/List/elements.tsx +35 -13
  305. package/src/components/List/index.tsx +12 -4
  306. package/src/components/List/scroll.ts +8 -3
  307. package/src/components/List/types.ts +13 -4
  308. package/src/components/List/useScrollEdgeDetection.ts +59 -0
  309. package/src/components/PaginationIndicator/ImperativePaginationIndicator.tsx +35 -0
  310. package/src/components/PaginationIndicator/index.tsx +1 -0
  311. package/src/components/PaginationIndicator/types.ts +11 -0
  312. package/src/components/Touchable/index.tsx +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/web",
3
- "version": "7.0.2",
3
+ "version": "7.1.1",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -22,15 +22,15 @@
22
22
  },
23
23
  "license": "UNLICENSED",
24
24
  "devDependencies": {
25
- "@codeleap/config": "7.0.1",
26
- "@codeleap/form": "7.0.1",
27
- "@codeleap/hooks": "7.0.1",
28
- "@codeleap/logger": "7.0.1",
29
- "@codeleap/query": "7.0.1",
30
- "@codeleap/styles": "7.0.1",
31
- "@codeleap/types": "7.0.1",
32
- "@codeleap/utils": "7.0.1",
33
- "@codeleap/store": "7.0.1",
25
+ "@codeleap/config": "7.0.2",
26
+ "@codeleap/form": "7.0.2",
27
+ "@codeleap/hooks": "7.0.2",
28
+ "@codeleap/logger": "7.0.2",
29
+ "@codeleap/query": "7.0.2",
30
+ "@codeleap/styles": "7.0.2",
31
+ "@codeleap/types": "7.0.2",
32
+ "@codeleap/utils": "7.0.2",
33
+ "@codeleap/store": "7.0.2",
34
34
  "@tanstack/react-query": "5.100.9"
35
35
  },
36
36
  "scripts": {
@@ -60,13 +60,13 @@
60
60
  "uuid": "13.0.0"
61
61
  },
62
62
  "peerDependencies": {
63
- "@codeleap/types": "7.0.1",
64
- "@codeleap/utils": "7.0.1",
65
- "@codeleap/hooks": "7.0.1",
66
- "@codeleap/query": "7.0.1",
67
- "@codeleap/logger": "7.0.1",
68
- "@codeleap/styles": "7.0.1",
69
- "@codeleap/store": "7.0.1",
63
+ "@codeleap/types": "7.0.2",
64
+ "@codeleap/utils": "7.0.2",
65
+ "@codeleap/hooks": "7.0.2",
66
+ "@codeleap/query": "7.0.2",
67
+ "@codeleap/logger": "7.0.2",
68
+ "@codeleap/styles": "7.0.2",
69
+ "@codeleap/store": "7.0.2",
70
70
  "@emotion/react": "11.14.0",
71
71
  "@reach/router": "^1.3.4",
72
72
  "dayjs": "1.11.18",
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useImperativeHandle, useMemo } from 'react'
1
+ import React, { useCallback, useImperativeHandle, useMemo, useRef } from 'react'
2
2
  import {
3
3
  useMasonry,
4
4
  usePositioner,
@@ -11,6 +11,7 @@ import { TypeGuards } from '@codeleap/types'
11
11
  import { View, ViewProps } from '../View'
12
12
  import { useListContext } from './context'
13
13
  import { AugmentedRenderItemInfo, ListHandle, ListItem, ListItemsProps } from './types'
14
+ import { useScrollEdgeDetection } from './useScrollEdgeDetection'
14
15
 
15
16
  /**
16
17
  * Outer `View` that measures its own dimensions for the Masonic positioner via a `ResizeObserver`.
@@ -28,16 +29,26 @@ export const ListWrapper = ({ children, ...viewProps }: ViewProps) => {
28
29
  function _ListItemsContent<T extends ListItem>({
29
30
  data,
30
31
  renderItem: providedRenderItem,
31
- fetchNextPage: itemsFetchNextPage,
32
- hasNextPage: itemsHasNextPage,
32
+ infiniteLoaderCallback: itemsInfiniteLoaderCallback,
33
+ hasMore: itemsHasMore,
34
+ onEndReached: itemsOnEndReached,
35
+ onEndReachedThreshold: itemsOnEndReachedThreshold,
36
+ onStartReached: itemsOnStartReached,
37
+ onStartReachedThreshold: itemsOnStartReachedThreshold,
33
38
  ref,
34
39
  }: ListItemsProps<T>) {
35
40
  const { wrapperRef, wrapperLayout, scrollHook, styles, props, padding } = useListContext()
36
41
 
37
- const fetchNextPage = itemsFetchNextPage ?? props.fetchNextPage
38
- const hasNextPage = itemsHasNextPage ?? props.hasNextPage
42
+ const infiniteLoaderCallback = itemsInfiniteLoaderCallback ?? props.infiniteLoaderCallback
43
+ const hasMore = itemsHasMore ?? props.hasMore
44
+ const onEndReached = itemsOnEndReached ?? props.onEndReached
45
+ const onEndReachedThreshold = itemsOnEndReachedThreshold ?? props.onEndReachedThreshold
46
+ const onStartReached = itemsOnStartReached ?? props.onStartReached
47
+ const onStartReachedThreshold = itemsOnStartReachedThreshold ?? props.onStartReachedThreshold
39
48
 
40
- const { scrollTop, isScrolling, height, width, scrollElement } = scrollHook(wrapperRef, wrapperLayout)
49
+ const useScrollBasedLoading = !!onEndReached || !!onStartReached
50
+
51
+ const { scrollTop, scrollHeight, isScrolling, height, width, scrollElement } = scrollHook(wrapperRef, wrapperLayout)
41
52
  const innerWidth = width - padding.paddingLeft - padding.paddingRight
42
53
 
43
54
  const stylePositioner = (styles as any).positioner ?? {}
@@ -69,12 +80,24 @@ function _ListItemsContent<T extends ListItem>({
69
80
  },
70
81
  }), [scrollToIndexFn])
71
82
 
83
+ useScrollEdgeDetection({
84
+ scrollTop,
85
+ scrollHeight,
86
+ clientHeight: height,
87
+ onEndReached,
88
+ onEndReachedThreshold,
89
+ onStartReached,
90
+ onStartReachedThreshold,
91
+ })
92
+
72
93
  const maybeLoadMore = useInfiniteLoader(
73
- async () => {
74
- if (hasNextPage) fetchNextPage?.()
75
- },
94
+ useScrollBasedLoading
95
+ ? async () => {}
96
+ : async () => { if (hasMore) infiniteLoaderCallback?.() },
76
97
  {
77
98
  isItemLoaded: (index, items) => !!items?.[index],
99
+ minimumBatchSize: 10,
100
+ threshold: 4,
78
101
  ...props.infiniteLoaderProps,
79
102
  }
80
103
  )
@@ -92,7 +115,7 @@ function _ListItemsContent<T extends ListItem>({
92
115
  const isFirst = index === 0
93
116
  const isLast = index === dataLength - 1
94
117
  const isOnly = dataLength === 1
95
-
118
+
96
119
  return <>
97
120
  {isFirst ? null : separator}
98
121
  {providedRenderItem({
@@ -104,7 +127,7 @@ function _ListItemsContent<T extends ListItem>({
104
127
  } as AugmentedRenderItemInfo<T>)}
105
128
  </>
106
129
  }, [providedRenderItem, separator, dataLength])
107
-
130
+
108
131
  return useMasonry({
109
132
  positioner,
110
133
  resizeObserver,
@@ -112,9 +135,8 @@ function _ListItemsContent<T extends ListItem>({
112
135
  scrollTop,
113
136
  isScrolling,
114
137
  items: data ?? [],
115
-
116
138
  render: wrappedRenderItem,
117
- onRender: maybeLoadMore,
139
+ onRender: useScrollBasedLoading ? undefined : maybeLoadMore,
118
140
  })
119
141
  }
120
142
 
@@ -19,8 +19,12 @@ export function List<T extends ListItem>(props: ListProps<T>) {
19
19
  const {
20
20
  data,
21
21
  renderItem,
22
- fetchNextPage,
23
- hasNextPage,
22
+ infiniteLoaderCallback,
23
+ hasMore,
24
+ onEndReached,
25
+ onEndReachedThreshold,
26
+ onStartReached,
27
+ onStartReachedThreshold,
24
28
  ...providerProps
25
29
  } = { ...List.defaultProps, ...props } as ListProps<T>
26
30
 
@@ -31,8 +35,12 @@ export function List<T extends ListItem>(props: ListProps<T>) {
31
35
  <ListItems
32
36
  data={data}
33
37
  renderItem={renderItem}
34
- fetchNextPage={fetchNextPage}
35
- hasNextPage={hasNextPage}
38
+ infiniteLoaderCallback={infiniteLoaderCallback}
39
+ hasMore={hasMore}
40
+ onEndReached={onEndReached}
41
+ onEndReachedThreshold={onEndReachedThreshold}
42
+ onStartReached={onStartReached}
43
+ onStartReachedThreshold={onStartReachedThreshold}
36
44
  />
37
45
  <ListFooter />
38
46
  </ListWrapper>
@@ -8,9 +8,10 @@ import { useIsomorphicEffect } from '../../lib/hooks/useIsomorphicEffect'
8
8
  import { useWindowSize } from '../../lib/hooks/useWindowSize'
9
9
  import { UseListScrollHook, ListWrapperLayout } from './types'
10
10
 
11
- function useElementScroller(ref: React.RefObject<HTMLElement>): { scrollTop: number; isScrolling: boolean } {
11
+ function useElementScroller(ref: React.RefObject<HTMLElement>): { scrollTop: number; scrollHeight: number; isScrolling: boolean } {
12
12
  const [isScrolling, setIsScrolling] = useState(false)
13
13
  const [scrollTop, setScrollTop] = useState(0)
14
+ const [scrollHeight, setScrollHeight] = useState(0)
14
15
 
15
16
  useIsomorphicEffect(() => {
16
17
  if (typeof window === 'undefined') return
@@ -22,6 +23,7 @@ function useElementScroller(ref: React.RefObject<HTMLElement>): { scrollTop: num
22
23
  if (tick) return
23
24
  tick = window.requestAnimationFrame(() => {
24
25
  setScrollTop(current.scrollTop)
26
+ setScrollHeight(current.scrollHeight)
25
27
  tick = void 0
26
28
  })
27
29
  }
@@ -44,7 +46,7 @@ function useElementScroller(ref: React.RefObject<HTMLElement>): { scrollTop: num
44
46
  return () => window.clearTimeout(to)
45
47
  }, [scrollTop])
46
48
 
47
- return { scrollTop, isScrolling }
49
+ return { scrollTop, scrollHeight, isScrolling }
48
50
  }
49
51
 
50
52
  /**
@@ -53,9 +55,10 @@ function useElementScroller(ref: React.RefObject<HTMLElement>): { scrollTop: num
53
55
  * This is the default scroll hook; override via `ListProviderProps.scrollHook` or set `windowScroll` to switch to `useWindowScroll`.
54
56
  */
55
57
  export const useElementScroll: UseListScrollHook = (wrapperRef: React.RefObject<HTMLElement>, layout: ListWrapperLayout | null) => {
56
- const { scrollTop, isScrolling } = useElementScroller(wrapperRef)
58
+ const { scrollTop, scrollHeight, isScrolling } = useElementScroller(wrapperRef)
57
59
  return {
58
60
  scrollTop,
61
+ scrollHeight,
59
62
  isScrolling,
60
63
  height: layout?.offsetHeight ?? 0,
61
64
  width: layout?.width ?? 0,
@@ -73,8 +76,10 @@ export const useWindowScroll: UseListScrollHook = (wrapperRef: React.RefObject<H
73
76
  const windowHeight = windowSize[1]
74
77
  const { offset } = useContainerPosition(wrapperRef, windowSize)
75
78
  const { scrollTop, isScrolling } = useMasonicScroller(offset)
79
+ const scrollHeight = typeof document !== 'undefined' ? document.documentElement.scrollHeight : 0
76
80
  return {
77
81
  scrollTop,
82
+ scrollHeight,
78
83
  isScrolling,
79
84
  height: windowHeight,
80
85
  width: layout?.width ?? 0,
@@ -45,6 +45,7 @@ export type UseListScrollHook = (
45
45
  wrapperLayout: ListWrapperLayout | null
46
46
  ) => {
47
47
  scrollTop: number
48
+ scrollHeight: number
48
49
  isScrolling: boolean
49
50
  height: number
50
51
  width: number
@@ -66,9 +67,13 @@ export type ListHandle = {
66
67
  export type ListProviderProps = Partial<ListPositionerConfig> & ListPaddingProps & {
67
68
  scrollHook?: UseListScrollHook
68
69
  windowScroll?: boolean
69
- fetchNextPage?: () => void
70
- hasNextPage?: boolean
70
+ infiniteLoaderCallback?: () => void
71
+ hasMore?: boolean
71
72
  infiniteLoaderProps?: UseInfiniteLoaderOptions<unknown>
73
+ onEndReached?: () => void
74
+ onEndReachedThreshold?: number
75
+ onStartReached?: () => void
76
+ onStartReachedThreshold?: number
72
77
  separators?: boolean
73
78
  ItemSeparatorComponent?: React.ReactElement
74
79
  style?: StyleProp<ListComposition, keyof ListStyleDef>
@@ -83,8 +88,12 @@ export type ListProviderProps = Partial<ListPositionerConfig> & ListPaddingProps
83
88
  export type ListItemsProps<T extends ListItem> = {
84
89
  data: T[]
85
90
  renderItem: (data: AugmentedRenderItemInfo<T>) => React.ReactElement
86
- fetchNextPage?: () => void
87
- hasNextPage?: boolean
91
+ infiniteLoaderCallback?: () => void
92
+ hasMore?: boolean
93
+ onEndReached?: () => void
94
+ onEndReachedThreshold?: number
95
+ onStartReached?: () => void
96
+ onStartReachedThreshold?: number
88
97
  ref?: React.Ref<ListHandle>
89
98
  }
90
99
 
@@ -0,0 +1,59 @@
1
+ import { useEffect, useRef } from 'react'
2
+
3
+ type UseScrollEdgeDetectionOptions = {
4
+ scrollTop: number
5
+ scrollHeight: number
6
+ clientHeight: number
7
+ onEndReached?: () => void
8
+ onEndReachedThreshold?: number
9
+ onStartReached?: () => void
10
+ onStartReachedThreshold?: number
11
+ }
12
+
13
+ const DEFAULT_THRESHOLD = 0.5
14
+
15
+ export function useScrollEdgeDetection(options: UseScrollEdgeDetectionOptions) {
16
+ const {
17
+ scrollTop,
18
+ scrollHeight,
19
+ clientHeight,
20
+ onEndReached,
21
+ onEndReachedThreshold = DEFAULT_THRESHOLD,
22
+ onStartReached,
23
+ onStartReachedThreshold = DEFAULT_THRESHOLD,
24
+ } = options
25
+
26
+ const hasFiredEnd = useRef(false)
27
+ const hasFiredStart = useRef(false)
28
+
29
+ useEffect(() => {
30
+ if (clientHeight <= 0 || scrollHeight <= 0) return
31
+
32
+ if (onEndReached) {
33
+ const distanceFromEnd = scrollHeight - scrollTop - clientHeight
34
+ const endThreshold = clientHeight * onEndReachedThreshold
35
+
36
+ if (distanceFromEnd <= endThreshold) {
37
+ if (!hasFiredEnd.current) {
38
+ hasFiredEnd.current = true
39
+ onEndReached()
40
+ }
41
+ } else {
42
+ hasFiredEnd.current = false
43
+ }
44
+ }
45
+
46
+ if (onStartReached) {
47
+ const startThreshold = clientHeight * onStartReachedThreshold
48
+
49
+ if (scrollTop <= startThreshold) {
50
+ if (!hasFiredStart.current) {
51
+ hasFiredStart.current = true
52
+ onStartReached()
53
+ }
54
+ } else {
55
+ hasFiredStart.current = false
56
+ }
57
+ }
58
+ }, [scrollTop, scrollHeight, clientHeight, onEndReached, onEndReachedThreshold, onStartReached, onStartReachedThreshold])
59
+ }
@@ -0,0 +1,35 @@
1
+ import React, { useState, useImperativeHandle } from 'react'
2
+ import { PaginationIndicator } from './index'
3
+ import { PaginationIndicatorHandle, PaginationIndicatorProps, PaginationIndicatorState } from './types'
4
+
5
+ type ImperativePaginationIndicatorProps = Omit<PaginationIndicatorProps, 'isFetching' | 'hasMore' | 'noMoreItemsText'> & {
6
+ initialState?: PaginationIndicatorState
7
+ ref?: React.Ref<PaginationIndicatorHandle>
8
+ }
9
+
10
+ /**
11
+ * Self-contained pagination indicator that manages its own render state.
12
+ * The parent pushes updates via the ref handle instead of passing reactive props, avoiding full tree re-renders.
13
+ */
14
+ export const ImperativePaginationIndicator = (props: ImperativePaginationIndicatorProps) => {
15
+ const { initialState, ref, ...rest } = props
16
+
17
+ const [state, setState] = useState<PaginationIndicatorState>({
18
+ isFetching: false,
19
+ hasMore: true,
20
+ ...initialState,
21
+ })
22
+
23
+ useImperativeHandle(ref, () => ({
24
+ update: (next) => setState(prev => ({ ...prev, ...next })),
25
+ }), [])
26
+
27
+ return (
28
+ <PaginationIndicator
29
+ {...rest}
30
+ isFetching={state.isFetching}
31
+ hasMore={state.hasMore}
32
+ noMoreItemsText={state.noMoreItemsText}
33
+ />
34
+ )
35
+ }
@@ -10,6 +10,7 @@ import { AnyRecord, IJSX, StyledComponentProps, useNestedStylesByKey } from '@co
10
10
 
11
11
  export * from './styles'
12
12
  export * from './types'
13
+ export { ImperativePaginationIndicator } from './ImperativePaginationIndicator'
13
14
 
14
15
  /**
15
16
  * Status indicator placed at the bottom of a paginated or infinite-scroll list — shows a spinner while fetching, a "no more items" message when exhausted, or nothing otherwise.
@@ -5,6 +5,17 @@ import { ComponentCommonProps } from '../../types'
5
5
  import { PaginationIndicatorComposition } from './styles'
6
6
  import { StyleProp } from '@codeleap/styles'
7
7
 
8
+ export type PaginationIndicatorState = {
9
+ isFetching?: boolean
10
+ hasMore?: boolean
11
+ noMoreItemsText?: React.ReactElement | string | number
12
+ }
13
+
14
+ /** Imperative handle for updating a `PaginationIndicator` without re-rendering its parent. */
15
+ export type PaginationIndicatorHandle = {
16
+ update: (state: PaginationIndicatorState) => void
17
+ }
18
+
8
19
  export interface PaginationIndicatorStyleDef {}
9
20
 
10
21
  /**
@@ -118,7 +118,8 @@ Touchable.rootElement = 'wrapper'
118
118
  Touchable.defaultProps = {
119
119
  propagate: true,
120
120
  debounce: null,
121
- component: 'button',
121
+ component: 'div',
122
+ role: 'button',
122
123
  analyticsEnabled: false,
123
124
  analyticsName: null,
124
125
  analyticsData: {},