@codeleap/web 3.25.0 → 3.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/package.json +1 -2
  2. package/src/components/ActionIcon/index.tsx +52 -51
  3. package/src/components/ActionIcon/styles.ts +5 -1
  4. package/src/components/ActivityIndicator/index.tsx +55 -34
  5. package/src/components/ActivityIndicator/styles.ts +6 -0
  6. package/src/components/Badge/index.tsx +80 -43
  7. package/src/components/Badge/styles.ts +11 -1
  8. package/src/components/Button/index.tsx +89 -46
  9. package/src/components/Button/styles.ts +5 -0
  10. package/src/components/Checkbox/index.tsx +97 -83
  11. package/src/components/Checkbox/styles.ts +5 -1
  12. package/src/components/Collapse/index.tsx +83 -41
  13. package/src/components/Collapse/styles.ts +6 -3
  14. package/src/components/ColorPicker/index.tsx +48 -95
  15. package/src/components/ColorPicker/styles.ts +11 -11
  16. package/src/components/ColorPicker/types.ts +12 -26
  17. package/src/components/CropPicker/index.tsx +104 -100
  18. package/src/components/CropPicker/styles.ts +7 -0
  19. package/src/components/CropPicker/types.ts +17 -8
  20. package/src/{lib/hooks/useCropPicker.ts → components/CropPicker/useCropPicker.tsx} +15 -68
  21. package/src/components/CropPicker/utils.ts +51 -0
  22. package/src/components/DatePicker/{components → defaultComponents}/Header.tsx +17 -9
  23. package/src/components/DatePicker/{components → defaultComponents}/OuterInput.tsx +7 -6
  24. package/src/components/DatePicker/index.tsx +124 -110
  25. package/src/components/DatePicker/styles.ts +12 -1
  26. package/src/components/DatePicker/types.ts +33 -16
  27. package/src/components/Drawer/index.tsx +125 -133
  28. package/src/components/Drawer/styles.ts +5 -0
  29. package/src/components/Dropzone/index.tsx +63 -87
  30. package/src/components/Dropzone/styles.ts +6 -0
  31. package/src/components/Dropzone/types.ts +37 -29
  32. package/src/components/EmptyPlaceholder/index.tsx +83 -63
  33. package/src/components/EmptyPlaceholder/styles.ts +5 -0
  34. package/src/components/FileInput.tsx +91 -0
  35. package/src/components/Grid/index.tsx +41 -40
  36. package/src/components/Grid/styles.ts +9 -2
  37. package/src/components/Grid/types.ts +12 -10
  38. package/src/components/Icon/index.tsx +47 -45
  39. package/src/components/Icon/styles.ts +8 -0
  40. package/src/components/InputBase/index.tsx +42 -71
  41. package/src/components/InputBase/styles.ts +47 -37
  42. package/src/components/InputBase/types.ts +7 -19
  43. package/src/components/InputBase/utils.ts +23 -3
  44. package/src/components/List/ListLayout.tsx +37 -20
  45. package/src/components/List/PaginationIndicator.tsx +102 -0
  46. package/src/components/List/index.tsx +41 -36
  47. package/src/components/List/styles.ts +11 -5
  48. package/src/components/List/types.ts +20 -30
  49. package/src/components/List/useInfiniteScroll.ts +159 -0
  50. package/src/components/LoadingOverlay/index.tsx +33 -31
  51. package/src/components/LoadingOverlay/styles.ts +8 -3
  52. package/src/components/Modal/index.tsx +160 -98
  53. package/src/components/Modal/styles.ts +5 -0
  54. package/src/components/NumberIncrement/index.tsx +98 -67
  55. package/src/components/NumberIncrement/styles.ts +5 -0
  56. package/src/components/Overlay/index.tsx +35 -37
  57. package/src/components/Overlay/styles.ts +5 -3
  58. package/src/components/Pager/index.tsx +81 -65
  59. package/src/components/Pager/styles.ts +9 -3
  60. package/src/components/Progress/Bar/index.tsx +50 -45
  61. package/src/components/Progress/Bar/styles.tsx +7 -0
  62. package/src/components/Progress/Bar/types.tsx +30 -0
  63. package/src/components/Progress/Circle/index.tsx +48 -45
  64. package/src/components/Progress/Circle/styles.ts +8 -1
  65. package/src/components/Progress/Circle/types.ts +22 -10
  66. package/src/components/RadioInput/index.tsx +124 -78
  67. package/src/components/RadioInput/styles.ts +6 -0
  68. package/src/components/Scroll/index.tsx +32 -0
  69. package/src/components/Scroll/styles.ts +8 -0
  70. package/src/components/SearchInput/index.tsx +10 -10
  71. package/src/components/SectionFilters/index.tsx +36 -47
  72. package/src/components/SectionFilters/styles.ts +5 -1
  73. package/src/components/SectionFilters/types.ts +13 -14
  74. package/src/components/SegmentedControl/SegmentedControlOption.tsx +84 -0
  75. package/src/components/SegmentedControl/index.tsx +89 -111
  76. package/src/components/SegmentedControl/styles.ts +21 -7
  77. package/src/components/Select/index.tsx +58 -92
  78. package/src/components/Select/styles.ts +36 -19
  79. package/src/components/Select/types.ts +13 -17
  80. package/src/components/Slider/index.tsx +93 -85
  81. package/src/components/Slider/styles.ts +6 -13
  82. package/src/components/Switch/index.tsx +74 -63
  83. package/src/components/Switch/styles.ts +6 -1
  84. package/src/components/Tag/index.tsx +44 -39
  85. package/src/components/Tag/styles.ts +9 -1
  86. package/src/components/Tag/types.ts +10 -10
  87. package/src/components/Text/index.tsx +48 -37
  88. package/src/components/Text/styles.ts +8 -0
  89. package/src/components/Text/types.ts +8 -8
  90. package/src/components/TextEditor/index.tsx +28 -49
  91. package/src/components/TextEditor/styles.ts +8 -1
  92. package/src/components/TextEditor/types.ts +6 -11
  93. package/src/components/TextInput/index.tsx +96 -58
  94. package/src/components/TextInput/mask.tsx +50 -2
  95. package/src/components/TextInput/styles.ts +8 -3
  96. package/src/components/Tooltip/index.tsx +84 -61
  97. package/src/components/Tooltip/styles.ts +10 -3
  98. package/src/components/Touchable/index.tsx +86 -43
  99. package/src/components/Touchable/styles.ts +6 -0
  100. package/src/components/View/index.tsx +50 -36
  101. package/src/components/View/styles.ts +6 -0
  102. package/src/components/View/types.ts +15 -14
  103. package/src/components/components.ts +3 -2
  104. package/src/components/defaultStyles.ts +79 -0
  105. package/src/index.ts +0 -1
  106. package/src/lib/hooks/index.ts +0 -5
  107. package/src/lib/hooks/useBreakpointMatch.ts +7 -8
  108. package/src/lib/hooks/useMediaQuery.ts +3 -4
  109. package/src/lib/hooks/usePagination.ts +63 -79
  110. package/src/lib/index.ts +0 -1
  111. package/src/lib/utils/index.ts +0 -1
  112. package/src/lib/utils/test.ts +2 -2
  113. package/src/components/ActionIcon/types.ts +0 -15
  114. package/src/components/ActivityIndicator/types.ts +0 -12
  115. package/src/components/Badge/types.ts +0 -28
  116. package/src/components/Button/types.ts +0 -25
  117. package/src/components/Checkbox/types.ts +0 -15
  118. package/src/components/Collapse/types.ts +0 -11
  119. package/src/components/Drawer/types.ts +0 -23
  120. package/src/components/EmptyPlaceholder/types.ts +0 -32
  121. package/src/components/FileInput/index.tsx +0 -72
  122. package/src/components/FileInput/types.ts +0 -14
  123. package/src/components/Icon/types.ts +0 -15
  124. package/src/components/LoadingOverlay/types.ts +0 -16
  125. package/src/components/Modal/types.ts +0 -55
  126. package/src/components/NumberIncrement/types.ts +0 -29
  127. package/src/components/Overlay/types.ts +0 -13
  128. package/src/components/Pager/types.ts +0 -35
  129. package/src/components/PaginationButtons/index.tsx +0 -173
  130. package/src/components/PaginationButtons/styles.ts +0 -7
  131. package/src/components/PaginationButtons/types.ts +0 -26
  132. package/src/components/PaginationIndicator/index.tsx +0 -69
  133. package/src/components/PaginationIndicator/styles.ts +0 -3
  134. package/src/components/PaginationIndicator/types.ts +0 -18
  135. package/src/components/Progress/Bar/styles.ts +0 -10
  136. package/src/components/Progress/Bar/types.ts +0 -26
  137. package/src/components/RadioInput/types.ts +0 -29
  138. package/src/components/SegmentedControl/types.ts +0 -44
  139. package/src/components/Slider/types.ts +0 -29
  140. package/src/components/Switch/types.ts +0 -13
  141. package/src/components/TextInput/types.ts +0 -85
  142. package/src/components/Tooltip/types.ts +0 -46
  143. package/src/components/Touchable/types.ts +0 -22
  144. package/src/lib/WebStyleRegistry.ts +0 -51
  145. package/src/lib/hooks/useFileInput.ts +0 -15
  146. package/src/lib/hooks/useInfiniteScroll.ts +0 -77
  147. package/src/lib/hooks/useRefresh.ts +0 -87
  148. package/src/lib/hooks/useStylesFor.ts +0 -13
  149. package/src/lib/utils/cache.ts +0 -9
  150. /package/src/components/DatePicker/{components → defaultComponents}/index.tsx +0 -0
@@ -1,41 +1,68 @@
1
1
  import React from 'react'
2
+ import { useDefaultComponentStyle } from '@codeleap/common'
2
3
  import { View, ViewProps } from '../View'
3
4
  import { EmptyPlaceholder } from '../EmptyPlaceholder'
4
- import { ListItem, ListProps } from './types'
5
- import { ItemMasonryProps, ListMasonry, useInfiniteScroll, useMasonryReload } from '../../lib'
6
- import { useStylesFor } from '../../lib/hooks/useStylesFor'
7
- import { WebStyleRegistry } from '../../lib/WebStyleRegistry'
8
- import { AnyRecord, IJSX, StyledComponentProps } from '@codeleap/styles'
5
+ import { ListPresets } from './styles'
6
+ import { useInfiniteScroll } from './useInfiniteScroll'
7
+ import { ListProps } from './types'
9
8
  import { ListLayout } from './ListLayout'
9
+ import { ItemMasonryProps, ListMasonry, useMasonryReload } from '../../lib'
10
10
 
11
11
  export * from './styles'
12
+ export * from './PaginationIndicator'
13
+ export * from './useInfiniteScroll'
12
14
  export * from './types'
13
15
  export * from './ListLayout'
14
16
 
15
- const RenderSeparator = (props: { separatorStyles: ViewProps['style'] }) => {
16
- return <View style={props?.separatorStyles} />
17
+ const RenderSeparator = (props: { separatorStyles: ViewProps<'div'>['css'] }) => {
18
+ return (
19
+ <View css={[props?.separatorStyles]}></View>
20
+ )
21
+ }
22
+
23
+ const defaultProps: Partial<ListProps> = {
24
+ ListFooterComponent: null,
25
+ ListHeaderComponent: null,
26
+ ListLoadingIndicatorComponent: null,
27
+ ListEmptyComponent: EmptyPlaceholder,
28
+ ListSeparatorComponent: RenderSeparator,
29
+ refreshDebounce: 1500,
30
+ refreshSize: 40,
31
+ refreshThreshold: 0.1,
32
+ refreshPosition: 16,
33
+ refresh: true,
34
+ rowItemsSpacing: 8,
35
+ overscan: 2,
36
+ reloadTimeout: 350,
37
+ showFooter: true,
17
38
  }
18
39
 
19
- export function List(props: ListProps) {
40
+ export function List<T = any>(props: ListProps<T>) {
20
41
  const allProps = {
21
42
  ...List.defaultProps,
22
43
  ...props,
23
44
  } as ListProps
24
45
 
25
46
  const {
47
+ variants = [],
48
+ responsiveVariants = {},
49
+ styles = {},
26
50
  renderItem: RenderItem,
27
51
  rowItemsSpacing,
28
52
  ListSeparatorComponent,
29
53
  data,
30
54
  overscan,
31
55
  separators,
32
- masonryProps,
56
+ masonryProps = {},
33
57
  reloadTimeout,
34
58
  showFooter,
35
- style,
36
59
  } = allProps
37
60
 
38
- const styles = useStylesFor(List.styleRegistryName, style)
61
+ const variantStyles = useDefaultComponentStyle<'u:List', typeof ListPresets>('u:List', {
62
+ variants,
63
+ responsiveVariants,
64
+ styles,
65
+ })
39
66
 
40
67
  const { layoutProps, onLoadMore } = useInfiniteScroll(allProps)
41
68
 
@@ -45,7 +72,7 @@ export function List(props: ListProps) {
45
72
  })
46
73
 
47
74
  const separator = React.useMemo(() => {
48
- return separators ? <ListSeparatorComponent separatorStyles={styles.separator} /> : null
75
+ return separators ? <ListSeparatorComponent separatorStyles={variantStyles.separator} /> : null
49
76
  }, [])
50
77
 
51
78
  const renderItem = React.useCallback((_item: ItemMasonryProps<any>) => {
@@ -75,7 +102,7 @@ export function List(props: ListProps) {
75
102
  <ListLayout
76
103
  {...allProps}
77
104
  {...layoutProps}
78
- styles={styles}
105
+ variantStyles={variantStyles}
79
106
  showFooter={reloadingLayout ? false : showFooter}
80
107
  >
81
108
  <ListMasonry
@@ -94,26 +121,4 @@ export function List(props: ListProps) {
94
121
  )
95
122
  }
96
123
 
97
- List.styleRegistryName = 'List'
98
- List.elements = ['wrapper', 'innerWrapper', 'separator', 'refreshControl', 'refreshControlIndicator']
99
- List.rootElement = 'wrapper'
100
-
101
- List.withVariantTypes = <S extends AnyRecord>(styles: S) => {
102
- return List as <T extends ListItem>(props: StyledComponentProps<ListProps<T>, typeof styles>) => IJSX
103
- }
104
-
105
- List.defaultProps = {
106
- ListEmptyComponent: EmptyPlaceholder,
107
- ListSeparatorComponent: RenderSeparator,
108
- refreshDebounce: 1500,
109
- refreshSize: 40,
110
- refreshThreshold: 0.1,
111
- refreshPosition: 16,
112
- refresh: true,
113
- rowItemsSpacing: 8,
114
- overscan: 2,
115
- reloadTimeout: 350,
116
- showFooter: true,
117
- } as Partial<ListProps>
118
-
119
- WebStyleRegistry.registerComponent(List)
124
+ List.defaultProps = defaultProps
@@ -1,11 +1,17 @@
1
+ import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
+ import { ViewComposition } from '../View'
1
3
 
2
- type ListStates = 'empty' | 'loading'
4
+ type ListStates = 'empty' | 'loading'
3
5
 
4
- export type ListParts =
5
- 'wrapper' |
6
- 'innerWrapper' |
7
- 'separator' |
6
+ export type ListParts =
7
+ ViewComposition |
8
+ 'innerWrapper' |
9
+ 'separator' |
8
10
  'refreshControl' |
9
11
  'refreshControlIndicator'
10
12
 
11
13
  export type ListComposition = `${ListParts}:${ListStates}` | ListParts
14
+
15
+ const createListStyle = createDefaultVariantFactory<ListComposition>()
16
+
17
+ export const ListPresets = includePresets(style => createListStyle(() => ({ wrapper: style })))
@@ -1,22 +1,13 @@
1
- import { StylesOf } from '@codeleap/common'
1
+ import { ComponentVariants, PropsOf, StylesOf } from '@codeleap/common'
2
2
  import { EmptyPlaceholderProps } from '../EmptyPlaceholder'
3
- import { ViewProps } from '../View'
4
- import { MotionProps } from 'framer-motion'
3
+ import { View, ViewProps } from '../View'
4
+ import { ListComposition, ListPresets } from './styles'
5
+ import { motion } from 'framer-motion'
5
6
  import { ActivityIndicatorProps } from '../ActivityIndicator'
6
7
  import { ComponentCommonProps } from '../../types'
7
- import { ItemMasonryProps, ListMasonryProps, UseInfiniteScrollArgs, UseInfiniteScrollReturn } from '../../lib'
8
- import { ListComposition } from './styles'
9
- import { StyledProp } from '@codeleap/styles'
10
-
11
- export type ListLayoutProps = Omit<ListProps, 'renderItem'> & UseInfiniteScrollReturn['layoutProps'] & {
12
- styles: StylesOf<ListComposition>
13
- children?: React.ReactNode
14
- showFooter?: boolean
15
- }
16
-
17
- export type ListRefreshControlComponent = Partial<ListLayoutProps> & {
18
- styles: StylesOf<ListComposition>
19
- }
8
+ import { UseInfiniteScrollArgs } from './useInfiniteScroll'
9
+ import { ItemMasonryProps, ListMasonryProps } from '../../lib'
10
+ import { ListLayoutProps } from './ListLayout'
20
11
 
21
12
  export type AugmentedRenderItemInfo<T> = ItemMasonryProps<T> & {
22
13
  item: T
@@ -25,27 +16,26 @@ export type AugmentedRenderItemInfo<T> = ItemMasonryProps<T> & {
25
16
  isOnly: boolean
26
17
  }
27
18
 
28
- export type ListItem = {
29
- id: string | number
30
- }
31
-
32
- export type ListProps<T extends ListItem = ListItem> =
33
- ComponentCommonProps &
34
- UseInfiniteScrollArgs &
35
- {
36
- data: T[]
19
+ export type ListProps<
20
+ T = any[],
21
+ Data = T extends Array<infer D> ? D : never
22
+ > =
23
+ ComponentVariants<typeof ListPresets> &
24
+ Omit<typeof View, 'variants' | 'styles'> & {
25
+ data: Data[]
37
26
  isFetching?: boolean
38
27
  hasNextPage?: boolean
39
28
  separators?: boolean
40
29
  onRefresh?: () => void
41
- placeholder?: Omit<EmptyPlaceholderProps, 'debugName'>
30
+ placeholder?: EmptyPlaceholderProps
31
+ styles?: StylesOf<ListComposition>
42
32
  keyExtractor?: (item: T, index: number) => string
43
33
  renderItem: (data: AugmentedRenderItemInfo<T>) => React.ReactElement
44
34
  ListFooterComponent?: (props: ListLayoutProps) => React.ReactElement
45
35
  ListLoadingIndicatorComponent?: () => React.ReactElement
46
36
  ListRefreshControlComponent?: () => React.ReactElement
47
37
  ListEmptyComponent?: React.FC | ((props: EmptyPlaceholderProps) => React.ReactElement)
48
- ListSeparatorComponent?: React.FC | ((props: { separatorStyles: ViewProps['style'] }) => React.ReactElement)
38
+ ListSeparatorComponent?: React.FC | ((props: { separatorStyles: ViewProps<'div'>['css'] }) => React.ReactElement)
49
39
  isLoading?: boolean
50
40
  isFetchingNextPage?: boolean
51
41
  fetchNextPage?: () => void
@@ -55,13 +45,13 @@ export type ListProps<T extends ListItem = ListItem> =
55
45
  refreshThreshold?: number
56
46
  refreshPosition?: number
57
47
  refresh?: boolean
58
- refreshControlProps?: Partial<MotionProps>
48
+ refreshControlProps?: PropsOf<typeof motion.div>
59
49
  refreshControlIndicatorProps?: Partial<ActivityIndicatorProps>
60
- style?: StyledProp<ListComposition>
50
+ style?: React.CSSProperties
61
51
  ref?: React.MutableRefObject<undefined>
62
52
  rowItemsSpacing?: number
63
53
  overscan?: number
64
54
  masonryProps?: Partial<ListMasonryProps<T>>
65
55
  reloadTimeout?: number
66
56
  showFooter?: boolean
67
- }
57
+ } & ComponentCommonProps & UseInfiniteScrollArgs
@@ -0,0 +1,159 @@
1
+ import React from 'react'
2
+ import { AnyFunction, TypeGuards, useEffect } from '@codeleap/common'
3
+ import { ListProps } from '.'
4
+ import { GridProps } from '../Grid'
5
+ import { useInfiniteLoader, LoadMoreItemsCallback, UseInfiniteLoaderOptions } from 'masonic'
6
+
7
+ export type UseInfiniteScrollArgs<Item extends Element = any> = {
8
+ threshold?: number
9
+ onLoadMore?: AnyFunction
10
+ loadMoreOptions?: Partial<UseInfiniteLoaderOptions<Item>>
11
+ }
12
+
13
+ export type UseInfiniteScrollProps<Item extends Element = any> =
14
+ Partial<ListProps> &
15
+ Partial<GridProps> &
16
+ UseInfiniteScrollArgs<Item>
17
+
18
+ export type UseInfiniteScrollReturn<Item extends Element = any> = {
19
+ onLoadMore: LoadMoreItemsCallback<Item>
20
+ isRefresh: boolean
21
+ layoutProps: {
22
+ isEmpty: boolean
23
+ refreshing: boolean
24
+ scrollableRef: React.MutableRefObject<undefined>
25
+ }
26
+ onRefreshItems: AnyFunction
27
+ }
28
+
29
+ type UseRefreshOptions = {
30
+ threshold: number
31
+ debounce: number
32
+ enabled: boolean
33
+ }
34
+
35
+ const scrollDebounce = (func, delay) => {
36
+ const timerRef = React.useRef(null)
37
+
38
+ const scrollDebounce = (...args) => {
39
+ clearTimeout(timerRef.current)
40
+ timerRef.current = setTimeout(() => {
41
+ func(...args)
42
+ }, delay)
43
+ }
44
+
45
+ return scrollDebounce
46
+ }
47
+
48
+ export const useRefresh = (onRefresh = () => null, options: UseRefreshOptions) => {
49
+ const {
50
+ threshold,
51
+ debounce,
52
+ enabled,
53
+ } = options
54
+
55
+ const [refresh, setRefresh] = React.useState(false)
56
+
57
+ const pushToTopRef = React.useRef(0)
58
+
59
+ const refresher = React.useCallback(async (_onRefresh: AnyFunction) => {
60
+ setRefresh(true)
61
+ await _onRefresh?.()
62
+
63
+ setTimeout(() => {
64
+ setRefresh(false)
65
+ pushToTopRef.current = 0
66
+ }, 2500)
67
+ }, [])
68
+
69
+ const containerRef = React.useRef(null)
70
+
71
+ const onScroll = scrollDebounce(() => {
72
+ if (containerRef.current) {
73
+ const rect = containerRef.current?.getBoundingClientRect()
74
+ const scrollTop = window?.pageYOffset || document?.documentElement?.scrollTop
75
+
76
+ const containerTop = rect.top + scrollTop
77
+ const containerHeight = rect.height
78
+
79
+ const distanceFromTop = Math.max(0, scrollTop - containerTop)
80
+ const distanceFromBottom = Math.max(0, containerTop + containerHeight - scrollTop)
81
+
82
+ const totalDistance = containerHeight + distanceFromTop + distanceFromBottom
83
+ const percentage = (distanceFromTop / totalDistance) * 100
84
+
85
+ if (percentage < threshold) {
86
+ if (pushToTopRef.current === 2) {
87
+ refresher(onRefresh)
88
+ }
89
+
90
+ pushToTopRef.current = pushToTopRef.current + 1
91
+ }
92
+ }
93
+ }, debounce)
94
+
95
+ useEffect(() => {
96
+ if (enabled) {
97
+ window.addEventListener('scroll', onScroll)
98
+
99
+ return () => {
100
+ window.removeEventListener('scroll', onScroll)
101
+ }
102
+ }
103
+ }, [enabled])
104
+
105
+ return {
106
+ refresh,
107
+ scrollableRef: containerRef,
108
+ refresher,
109
+ }
110
+ }
111
+
112
+ export function useInfiniteScroll<Item extends Element = any>(props: UseInfiniteScrollProps<Item>): UseInfiniteScrollReturn<Item> {
113
+ const {
114
+ onRefresh,
115
+ data,
116
+ hasNextPage,
117
+ refresh: refreshEnabled,
118
+ fetchNextPage,
119
+ refreshThreshold,
120
+ refreshDebounce,
121
+ loadMoreOptions = {},
122
+ onLoadMore,
123
+ threshold = 16,
124
+ } = props
125
+
126
+ const infiniteLoader = useInfiniteLoader(
127
+ async (args) => {
128
+ if (hasNextPage) await fetchNextPage?.()
129
+ if (TypeGuards.isFunction(onLoadMore)) await onLoadMore?.(args)
130
+ },
131
+ {
132
+ isItemLoaded: (index, items) => !!items?.[index],
133
+ threshold: threshold,
134
+ ...loadMoreOptions,
135
+ },
136
+ )
137
+
138
+ const refreshHookReturn = useRefresh(
139
+ onRefresh,
140
+ {
141
+ threshold: refreshThreshold,
142
+ debounce: refreshDebounce,
143
+ enabled: refreshEnabled,
144
+ }
145
+ )
146
+
147
+ const isEmpty = React.useMemo(() => (!data || !data?.length), [data?.length])
148
+
149
+ return {
150
+ onLoadMore: infiniteLoader,
151
+ isRefresh: refreshHookReturn.refresh,
152
+ layoutProps: {
153
+ scrollableRef: refreshHookReturn.scrollableRef,
154
+ refreshing: refreshHookReturn.refresh,
155
+ isEmpty,
156
+ },
157
+ onRefreshItems: refreshHookReturn.refresher,
158
+ }
159
+ }
@@ -1,47 +1,49 @@
1
+ import { ComponentVariants, getNestedStylesByKey, useDefaultComponentStyle } from '@codeleap/common'
1
2
  import React from 'react'
2
- import { View } from '../View'
3
- import { ActivityIndicator } from '../ActivityIndicator'
4
- import { LoadingOverlayProps } from './types'
5
- import { useStylesFor } from '../../lib/hooks/useStylesFor'
6
- import { AnyRecord, IJSX, StyledComponentProps, useNestedStylesByKey } from '@codeleap/styles'
7
- import { WebStyleRegistry } from '../../lib/WebStyleRegistry'
8
-
9
- export * from './styles'
10
- export * from './types'
3
+ import { StylesOf } from '../..'
4
+ import { LoadingOverlayComposition, LoadingOverlayPresets } from './styles'
5
+ import { View, ViewProps } from '../View'
6
+ import { ActivityIndicator, ActivityIndicatorProps } from '../ActivityIndicator'
7
+ import { ComponentCommonProps } from '../../types/utility'
8
+
9
+ export type LoadingOverlayProps = Partial<ViewProps<'div'>> & {
10
+ visible?: boolean
11
+ styles?: StylesOf<LoadingOverlayComposition>
12
+ style?: React.CSSProperties
13
+ indicatorProps?: ActivityIndicatorProps
14
+ children?: React.ReactNode
15
+ } & ComponentVariants<typeof LoadingOverlayPresets> & ComponentCommonProps
11
16
 
12
17
  export const LoadingOverlay = (props: LoadingOverlayProps) => {
13
- const {
18
+ const {
14
19
  visible,
15
20
  children,
16
- style,
21
+ styles = {},
22
+ variants = [],
23
+ responsiveVariants = {},
24
+ style = {},
17
25
  indicatorProps,
18
26
  debugName,
19
- ...rest
20
- } = {
21
- ...LoadingOverlay.defaultProps,
22
- ...props,
23
- }
27
+ ...rest
28
+ } = props
24
29
 
25
- const styles = useStylesFor(LoadingOverlay.styleRegistryName, style)
30
+ const variantStyles = useDefaultComponentStyle<'u:LoadingOverlay', typeof LoadingOverlayPresets>('u:LoadingOverlay', {
31
+ variants,
32
+ styles,
33
+ responsiveVariants,
34
+ rootElement: 'wrapper',
35
+ })
26
36
 
27
- const indicatorStyles = useNestedStylesByKey('indicator', styles)
37
+ const indicatorStyles = React.useMemo(() => {
38
+ return getNestedStylesByKey('indicator', variantStyles)
39
+ }, [variantStyles])
28
40
 
29
41
  return (
30
- <View {...rest} style={[styles.wrapper, visible && styles['wrapper:visible']]}>
31
- <ActivityIndicator debugName={debugName} {...indicatorProps} style={indicatorStyles} />
42
+ <View css={[variantStyles.wrapper, visible && variantStyles['wrapper:visible'], style]} {...rest}>
43
+ <ActivityIndicator debugName={debugName} {...indicatorProps} styles={indicatorStyles} />
32
44
  {children}
33
45
  </View>
34
46
  )
35
47
  }
36
48
 
37
- LoadingOverlay.styleRegistryName = 'LoadingOverlay'
38
- LoadingOverlay.elements = ['wrapper', 'indicator']
39
- LoadingOverlay.rootElement = 'wrapper'
40
-
41
- LoadingOverlay.withVariantTypes = <S extends AnyRecord>(styles: S) => {
42
- return LoadingOverlay as (props: StyledComponentProps<LoadingOverlayProps, typeof styles>) => IJSX
43
- }
44
-
45
- LoadingOverlay.defaultProps = {} as Partial<LoadingOverlayProps>
46
-
47
- WebStyleRegistry.registerComponent(LoadingOverlay)
49
+ export * from './styles'
@@ -1,7 +1,12 @@
1
- import { ActivityIndicatorComposition } from '../ActivityIndicator'
2
-
3
- type LoadingOverlayStates = 'visible'
1
+ import { createDefaultVariantFactory, includePresets } from "@codeleap/common";
2
+ import { ActivityIndicatorComposition } from "../ActivityIndicator";
4
3
 
4
+ type LoadingOverlayStates = 'visible'
5
+
5
6
  export type LoadingOverlayParts = 'wrapper' | `indicator${Capitalize<ActivityIndicatorComposition>}`
6
7
 
7
8
  export type LoadingOverlayComposition = `${LoadingOverlayParts}:${LoadingOverlayStates}` | LoadingOverlayParts
9
+
10
+ export const createLoadingOverlayStyle = createDefaultVariantFactory<LoadingOverlayComposition>()
11
+
12
+ export const LoadingOverlayPresets = includePresets(s => createLoadingOverlayStyle(() => ({wrapper: s})))