@codeleap/mobile 3.24.2 → 3.25.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 (131) hide show
  1. package/package.json +6 -4
  2. package/src/Registry.ts +52 -0
  3. package/src/components/ActionIcon/index.tsx +55 -37
  4. package/src/components/ActionIcon/styles.ts +2 -4
  5. package/src/components/ActionIcon/types.ts +15 -0
  6. package/src/components/ActivityIndicator/index.tsx +42 -64
  7. package/src/components/ActivityIndicator/styles.ts +1 -10
  8. package/src/components/ActivityIndicator/types.ts +9 -0
  9. package/src/components/Autocomplete/index.tsx +46 -54
  10. package/src/components/Autocomplete/styles.ts +2 -5
  11. package/src/components/Autocomplete/types.ts +13 -23
  12. package/src/components/Avatar/index.tsx +59 -71
  13. package/src/components/Avatar/styles.ts +1 -9
  14. package/src/components/Avatar/types.ts +23 -0
  15. package/src/components/AvatarGroup/index.tsx +30 -44
  16. package/src/components/AvatarGroup/styles.ts +0 -6
  17. package/src/components/AvatarGroup/types.ts +10 -0
  18. package/src/components/Backdrop/index.tsx +51 -34
  19. package/src/components/Backdrop/styles.ts +5 -10
  20. package/src/components/Backdrop/types.ts +14 -0
  21. package/src/components/Badge/index.tsx +36 -62
  22. package/src/components/Badge/styles.ts +3 -11
  23. package/src/components/Badge/types.ts +27 -0
  24. package/src/components/Button/index.tsx +55 -82
  25. package/src/components/Button/styles.ts +13 -14
  26. package/src/components/Button/types.ts +20 -0
  27. package/src/components/Calendar/index.tsx +35 -29
  28. package/src/components/Checkbox/index.tsx +43 -64
  29. package/src/components/Checkbox/styles.ts +1 -6
  30. package/src/components/Checkbox/types.ts +13 -0
  31. package/src/components/DatePickerModal/index.tsx +50 -65
  32. package/src/components/DatePickerModal/styles.ts +9 -10
  33. package/src/components/DatePickerModal/types.ts +36 -54
  34. package/src/components/EmptyPlaceholder/index.tsx +40 -63
  35. package/src/components/EmptyPlaceholder/styles.ts +0 -5
  36. package/src/components/EmptyPlaceholder/types.ts +21 -0
  37. package/src/components/FileInput/index.tsx +11 -49
  38. package/src/components/FileInput/types.ts +27 -0
  39. package/src/components/Grid/index.tsx +84 -116
  40. package/src/components/Grid/styles.ts +0 -5
  41. package/src/components/Grid/types.ts +20 -0
  42. package/src/components/Icon/index.tsx +44 -79
  43. package/src/components/Icon/styles.ts +0 -6
  44. package/src/components/Icon/types.ts +15 -0
  45. package/src/components/Image/index.tsx +58 -78
  46. package/src/components/Image/styles.ts +1 -6
  47. package/src/components/Image/types.ts +18 -0
  48. package/src/components/ImageView/Spotlight.tsx +1 -4
  49. package/src/components/ImageView/component.tsx +1 -2
  50. package/src/components/InputBase/index.tsx +33 -24
  51. package/src/components/InputBase/styles.ts +66 -75
  52. package/src/components/InputBase/types.ts +3 -4
  53. package/src/components/InputBase/utils.ts +6 -4
  54. package/src/components/List/index.tsx +99 -151
  55. package/src/components/List/styles.ts +0 -6
  56. package/src/components/List/types.ts +41 -0
  57. package/src/components/LoadingOverlay/index.tsx +42 -29
  58. package/src/components/LoadingOverlay/styles.ts +7 -7
  59. package/src/components/LoadingOverlay/types.ts +9 -0
  60. package/src/components/Modal/index.tsx +80 -127
  61. package/src/components/Modal/styles.ts +0 -8
  62. package/src/components/Modal/types.ts +41 -0
  63. package/src/components/Navigation/Navigation.tsx +1 -0
  64. package/src/components/Navigation/types.ts +2 -9
  65. package/src/components/NumberIncrement/index.tsx +50 -60
  66. package/src/components/NumberIncrement/styles.ts +0 -5
  67. package/src/components/NumberIncrement/types.ts +32 -39
  68. package/src/components/Pager/index.tsx +42 -94
  69. package/src/components/Pager/styles.ts +1 -13
  70. package/src/components/Pager/types.ts +37 -0
  71. package/src/components/PaginationIndicator/index.tsx +51 -0
  72. package/src/components/PaginationIndicator/styles.ts +3 -0
  73. package/src/components/PaginationIndicator/types.ts +10 -0
  74. package/src/components/RadioInput/index.tsx +32 -57
  75. package/src/components/RadioInput/styles.ts +5 -7
  76. package/src/components/RadioInput/types.ts +31 -0
  77. package/src/components/RefreshControl/index.tsx +39 -19
  78. package/src/components/RefreshControl/styles.ts +1 -6
  79. package/src/components/RefreshControl/types.ts +9 -0
  80. package/src/components/Scroll/index.tsx +89 -105
  81. package/src/components/Scroll/styles.ts +0 -5
  82. package/src/components/Scroll/types.ts +21 -0
  83. package/src/components/SearchInput/index.tsx +90 -0
  84. package/src/components/Sections/index.tsx +111 -161
  85. package/src/components/Sections/styles.ts +0 -5
  86. package/src/components/Sections/types.ts +39 -0
  87. package/src/components/SegmentedControl/Option.tsx +46 -31
  88. package/src/components/SegmentedControl/index.tsx +86 -121
  89. package/src/components/SegmentedControl/styles.ts +15 -22
  90. package/src/components/SegmentedControl/types.ts +31 -0
  91. package/src/components/Select/index.tsx +71 -82
  92. package/src/components/Select/styles.ts +3 -5
  93. package/src/components/Select/types.ts +20 -25
  94. package/src/components/Slider/index.tsx +58 -43
  95. package/src/components/Slider/styles.ts +15 -6
  96. package/src/components/Slider/types.ts +9 -14
  97. package/src/components/Switch/index.tsx +43 -56
  98. package/src/components/Switch/styles.ts +1 -7
  99. package/src/components/Switch/types.ts +12 -0
  100. package/src/components/Text/index.tsx +56 -52
  101. package/src/components/Text/styles.ts +1 -7
  102. package/src/components/Text/types.ts +18 -0
  103. package/src/components/TextInput/index.tsx +49 -162
  104. package/src/components/TextInput/styles.ts +2 -8
  105. package/src/components/TextInput/types.ts +23 -0
  106. package/src/components/Touchable/index.tsx +44 -87
  107. package/src/components/Touchable/styles.ts +0 -9
  108. package/src/components/Touchable/types.ts +27 -0
  109. package/src/components/View/index.tsx +23 -92
  110. package/src/components/View/styles.ts +0 -6
  111. package/src/components/View/types.ts +13 -0
  112. package/src/components/components.ts +2 -6
  113. package/src/hooks/index.ts +13 -0
  114. package/src/index.ts +2 -0
  115. package/src/modules/PressableRipple/type.ts +1 -0
  116. package/src/utils/KeyboardAware/context.tsx +0 -2
  117. package/src/utils/KeyboardAware/keyboardHooks.ts +1 -2
  118. package/src/utils/ModalManager/components.tsx +1 -30
  119. package/src/utils/ModalManager/context.tsx +4 -4
  120. package/src/utils/ModalManager/index.ts +1 -4
  121. package/src/utils/hooks.ts +12 -1
  122. package/src/components/Calendar/style.ts +0 -6
  123. package/src/components/ContentView/index.tsx +0 -63
  124. package/src/components/ContentView/styles.ts +0 -8
  125. package/src/components/Drawer/index.tsx +0 -28
  126. package/src/components/Drawer/styles.ts +0 -8
  127. package/src/components/FileInput/styles.ts +0 -8
  128. package/src/components/InputLabel/index.tsx +0 -38
  129. package/src/components/InputLabel/styles.ts +0 -7
  130. package/src/components/List/PaginationIndicator.tsx +0 -54
  131. package/src/components/defaultStyles.ts +0 -77
@@ -1,120 +1,104 @@
1
- import * as React from 'react'
2
- import { forwardRef, useState } from 'react'
3
- import {
4
- deepEqual,
5
- onUpdate,
6
- useDefaultComponentStyle,
7
- usePrevious,
8
- } from '@codeleap/common'
9
- import { ScrollView, StyleSheet } from 'react-native'
10
- import { ViewProps } from '../View'
11
- import { RefreshControl, RefreshControlProps } from '../RefreshControl'
12
- import { ComponentWithDefaultProps, StylesOf } from '../../types'
13
- import { ScrollComposition, ScrollPresets } from './styles'
14
- import { GetKeyboardAwarePropsOptions, useKeyboardPaddingStyle } from '../../utils'
15
- import { KeyboardAwareScrollView, KeyboardAwareScrollViewProps } from 'react-native-keyboard-aware-scroll-view'
16
- import { useSoftInputState } from 'react-native-avoid-softinput'
17
- import { useMemo } from 'react'
18
- export type ScrollProps = KeyboardAwareScrollViewProps &
19
- ViewProps & {
20
- onRefresh?: () => void
21
- refreshTimeout?: number
22
- changeData?: any
23
- keyboardAware?: boolean
24
- refreshing?: boolean
25
- styles?: StylesOf<ScrollComposition>
26
- refreshControlProps?: Partial<RefreshControlProps>
27
- debugName?: string
1
+ import React, { forwardRef, useState } from 'react'
2
+ import { deepEqual, onUpdate, usePrevious } from '@codeleap/common'
3
+ import { ScrollView } from 'react-native'
4
+ import { RefreshControl } from '../RefreshControl'
5
+ import { useKeyboardPaddingStyle } from '../../utils'
6
+ import { ScrollProps, ScrollRef } from './types'
7
+ import { AnyRecord, IJSX, StyledComponentProps, StyledComponentWithProps } from '@codeleap/styles'
8
+ import { MobileStyleRegistry } from '../../Registry'
9
+ import { useStylesFor } from '../../hooks'
10
+
11
+ export * from './styles'
12
+ export * from './types'
13
+
14
+ export const Scroll = forwardRef<ScrollRef, ScrollProps>((scrollProps, ref) => {
15
+ const {
16
+ style,
17
+ refreshTimeout,
18
+ children,
19
+ changeData,
20
+ refreshControlProps = {},
21
+ contentContainerStyle,
22
+ keyboardAware,
23
+ animated,
24
+ ...props
25
+ } = {
26
+ ...Scroll.defaultProps,
27
+ ...scrollProps,
28
28
  }
29
29
 
30
- export type ScrollRef = KeyboardAwareScrollView
30
+ const hasRefresh = !!props.onRefresh
31
+ const [refreshingState, setRefreshing] = useState(false)
32
+ const refreshingDisplay = props.refreshing !== undefined ? props.refreshing : refreshingState
31
33
 
32
- const defaultProps: Partial<ScrollProps> = {
33
- keyboardShouldPersistTaps: 'handled',
34
- }
34
+ const timer = React.useRef(null)
35
+ const previousData = usePrevious(changeData)
35
36
 
36
- export const Scroll = forwardRef<ScrollRef, ScrollProps>(
37
- (scrollProps, ref) => {
38
- const {
39
- variants = [],
40
- style,
41
- refreshTimeout = 3000,
42
- children,
43
- changeData,
44
- styles = {},
45
- refreshControlProps = {},
46
- contentContainerStyle,
47
- keyboardAware = true,
48
- animated = true,
49
- ...props
50
- } = {
51
- ...defaultProps,
52
- ...scrollProps,
37
+ const onRefresh = () => {
38
+ if (timer.current) {
39
+ clearTimeout(timer.current)
53
40
  }
54
- const hasRefresh = !!props.onRefresh
55
- const [refreshingState, setRefreshing] = useState(false)
56
- const refreshingDisplay = props.refreshing !== undefined ? props.refreshing : refreshingState
57
41
 
58
- const timer = React.useRef(null)
59
- const previousData = usePrevious(changeData)
42
+ setRefreshing(true)
60
43
 
61
- const onRefresh = () => {
44
+ props.onRefresh()
45
+
46
+ timer.current = setTimeout(() => {
47
+ setRefreshing(false)
48
+ }, refreshTimeout)
49
+ }
50
+
51
+ onUpdate(() => {
52
+ if (refreshingDisplay && !deepEqual(previousData, changeData)) {
53
+ setRefreshing(false)
62
54
  if (timer.current) {
63
55
  clearTimeout(timer.current)
64
56
  }
57
+ }
58
+ }, [refreshingDisplay, changeData])
65
59
 
66
- setRefreshing(true)
60
+ const styles = useStylesFor(Scroll.styleRegistryName, style)
67
61
 
68
- props.onRefresh()
62
+ const Component = ScrollView
69
63
 
70
- timer.current = setTimeout(() => {
71
- setRefreshing(false)
72
- }, refreshTimeout)
73
- }
74
- onUpdate(() => {
75
- if (refreshingDisplay && !deepEqual(previousData, changeData)) {
76
- setRefreshing(false)
77
- if (timer.current) {
78
- clearTimeout(timer.current)
79
- }
64
+ const keyboardStyle = useKeyboardPaddingStyle([styles?.content, contentContainerStyle], keyboardAware)
65
+
66
+ return (
67
+ <Component
68
+ showsVerticalScrollIndicator={false}
69
+ // @ts-ignore
70
+ ref={ref}
71
+ refreshControl={
72
+ hasRefresh && (
73
+ <RefreshControl
74
+ refreshing={refreshingDisplay}
75
+ onRefresh={onRefresh}
76
+ {...refreshControlProps}
77
+ />
78
+ )
80
79
  }
81
- }, [refreshingDisplay, changeData])
82
-
83
- const variantStyles = useDefaultComponentStyle<'u:Scroll', typeof ScrollPresets>('u:Scroll', {
84
- variants,
85
- styles,
86
- transform: StyleSheet.flatten,
87
- rootElement: 'content',
88
- })
89
-
90
- const Component = ScrollView
91
-
92
- const keyboardStyle = useKeyboardPaddingStyle([variantStyles.content, contentContainerStyle], keyboardAware)
93
-
94
- return (
95
- <Component
96
- style={[variantStyles.wrapper, style]}
97
- contentContainerStyle={keyboardStyle}
98
- showsVerticalScrollIndicator={false}
99
- // @ts-ignore
100
- ref={ref}
101
- refreshControl={
102
- hasRefresh && (
103
- <RefreshControl
104
- refreshing={refreshingDisplay}
105
- onRefresh={onRefresh}
106
- {...refreshControlProps}
107
- />
108
- )
109
- }
110
- {...props}
111
- >
112
- {children}
113
- </Component>
114
- )
115
- },
116
- ) as unknown as ComponentWithDefaultProps<ScrollProps>
117
-
118
- Scroll.defaultProps = defaultProps
80
+ {...props}
81
+ style={styles?.wrapper}
82
+ contentContainerStyle={keyboardStyle}
83
+ >
84
+ {children}
85
+ </Component>
86
+ )
87
+ }) as StyledComponentWithProps<ScrollProps>
119
88
 
120
- export * from './styles'
89
+ Scroll.styleRegistryName = 'Scroll'
90
+ Scroll.elements = ['wrapper', 'content']
91
+ Scroll.rootElement = 'wrapper'
92
+
93
+ Scroll.withVariantTypes = <S extends AnyRecord>(styles: S) => {
94
+ return Scroll as (props: StyledComponentProps<ScrollProps, typeof styles>) => IJSX
95
+ }
96
+
97
+ Scroll.defaultProps = {
98
+ keyboardShouldPersistTaps: 'handled',
99
+ refreshTimeout: 3000,
100
+ keyboardAware: true,
101
+ animated: true,
102
+ } as Partial<ScrollProps>
103
+
104
+ MobileStyleRegistry.registerComponent(Scroll)
@@ -1,7 +1,2 @@
1
- import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
1
 
3
2
  export type ScrollComposition = 'wrapper' |'content'
4
-
5
- const createScrollStyle = createDefaultVariantFactory<ScrollComposition>()
6
-
7
- export const ScrollPresets = includePresets(style => createScrollStyle(() => ({ content: style })))
@@ -0,0 +1,21 @@
1
+ import { StyledProp } from '@codeleap/styles'
2
+ import { KeyboardAwareScrollView, KeyboardAwareScrollViewProps } from 'react-native-keyboard-aware-scroll-view'
3
+ import { ScrollComposition } from './styles'
4
+ import { RefreshControlProps } from '../RefreshControl'
5
+ import { ViewProps } from '../View'
6
+
7
+ export type ScrollProps =
8
+ Omit<KeyboardAwareScrollViewProps, 'style'> &
9
+ Omit<ViewProps, 'style'> &
10
+ {
11
+ onRefresh?: () => void
12
+ refreshTimeout?: number
13
+ changeData?: any
14
+ keyboardAware?: boolean
15
+ refreshing?: boolean
16
+ refreshControlProps?: Partial<RefreshControlProps>
17
+ debugName?: string
18
+ style?: StyledProp<ScrollComposition>
19
+ }
20
+
21
+ export type ScrollRef = KeyboardAwareScrollView
@@ -0,0 +1,90 @@
1
+ import React, { useState } from 'react'
2
+ import { AppIcon } from '@codeleap/styles'
3
+ import { ComponentWithDefaultProps } from '../../types'
4
+ import { TextInputProps, TextInput } from '../TextInput'
5
+ import { TypeGuards } from '@codeleap/common'
6
+
7
+ export type SearchInputProps = {
8
+ onTypingChange: (isTyping: boolean) => void
9
+ onSearchChange: (search: string) => void
10
+ onValueChange?: (search: string) => void
11
+ onClear?: () => void
12
+ debugName: string
13
+ debounce?: number
14
+ clearIcon?: AppIcon
15
+ searchIcon?: AppIcon
16
+ placeholder: string
17
+ } & Partial<TextInputProps>
18
+
19
+ export const SearchInput: ComponentWithDefaultProps<SearchInputProps> = (props) => {
20
+ const {
21
+ debugName,
22
+ onClear,
23
+ onSearchChange,
24
+ onTypingChange,
25
+ clearIcon,
26
+ searchIcon,
27
+ debounce,
28
+ placeholder,
29
+ value,
30
+ onValueChange,
31
+ ...others
32
+ } = {
33
+ ...SearchInput.defaultProps,
34
+ ...props,
35
+ }
36
+
37
+ const [search, setSearch] = !TypeGuards.isNil(value) && !!onValueChange ? [value, onValueChange] : useState('')
38
+
39
+ const setSearchTimeout = React.useRef<NodeJS.Timeout | null>(null)
40
+
41
+ const handleChangeSearch = (value: string) => {
42
+ setSearch(value)
43
+
44
+ if (TypeGuards.isNil(debounce)) {
45
+ onSearchChange?.(value)
46
+ } else {
47
+ if (setSearchTimeout.current) {
48
+ clearTimeout(setSearchTimeout.current)
49
+ }
50
+
51
+ setSearchTimeout.current = setTimeout(() => {
52
+
53
+ onSearchChange(value)
54
+ onTypingChange?.(false)
55
+ }, debounce ?? 0)
56
+ }
57
+ }
58
+
59
+ const handleClear = () => {
60
+ setSearch('')
61
+ onSearchChange?.('')
62
+ onClear?.()
63
+ }
64
+
65
+ return (
66
+ <TextInput
67
+ value={search}
68
+ onChangeText={(value) => {
69
+ onTypingChange?.(true)
70
+ handleChangeSearch(value)
71
+ }}
72
+ placeholder={placeholder}
73
+ debugName={`Search ${debugName}`}
74
+ rightIcon={!!search?.trim?.() && {
75
+ name: clearIcon,
76
+ onPress: handleClear,
77
+ }}
78
+ leftIcon={{
79
+ name: searchIcon,
80
+ }}
81
+ {...others}
82
+ />
83
+ )
84
+ }
85
+
86
+ SearchInput.defaultProps = {
87
+ debounce: null,
88
+ clearIcon: 'x' as AppIcon,
89
+ searchIcon: 'search' as AppIcon,
90
+ } as Partial<SearchInputProps>
@@ -1,168 +1,118 @@
1
- import * as React from 'react'
2
- import { forwardRef } from 'react'
3
- import {
4
- useDefaultComponentStyle,
5
- ComponentVariants,
6
- useCallback,
7
- } from '@codeleap/common'
8
-
9
- import {
10
- RefreshControl,
11
- StyleSheet,
12
- RefreshControlProps,
13
- SectionListRenderItemInfo,
14
- SectionListProps as RNSectionListProps,
15
- SectionList,
16
- } from 'react-native'
17
- import { View, ViewProps } from '../View'
18
- import { EmptyPlaceholderProps } from '../EmptyPlaceholder'
19
- import { StylesOf } from '../../types'
1
+ import React, { forwardRef } from 'react'
2
+ import { useCallback } from '@codeleap/common'
3
+ import { RefreshControl, SectionList } from 'react-native'
4
+ import { View } from '../View'
20
5
  import { useKeyboardPaddingStyle } from '../../utils'
21
- import { SectionsComposition, SectionsPresets } from './styles'
22
- export * from './styles'
23
-
24
- export type DataboundSectionListPropsTypes = 'data' | 'renderItem' | 'keyExtractor' | 'getItemLayout'
25
-
26
- export type AugmentedSectionRenderItemInfo<T> = SectionListRenderItemInfo<T> & {
27
- isFirst: boolean
28
- isLast: boolean
29
- isOnly: boolean
30
- }
31
-
32
- export type ReplaceSectionListProps<P, T> = Omit<P, DataboundSectionListPropsTypes> & {
33
- sections: T[]
34
- keyExtractor?: (item: T, index: number) => string
35
- renderItem: (data: AugmentedSectionRenderItemInfo<T>) => React.ReactElement
36
- onRefresh?: () => void
37
- getItemLayout?: ((
38
- data: T,
39
- index: number,
40
- ) => { length: number; offset: number; index: number })
41
- fakeEmpty?: boolean
42
- }
6
+ import { SectionListProps } from './types'
7
+ import { AnyRecord, IJSX, StyledComponentProps, StyledComponentWithProps } from '@codeleap/styles'
8
+ import { MobileStyleRegistry } from '../../Registry'
9
+ import { useStylesFor } from '../../hooks'
43
10
 
44
11
  export * from './styles'
12
+ export * from './types'
13
+
14
+ export const Sections = forwardRef<SectionList, SectionListProps>((sectionsProps, ref) => {
15
+ const {
16
+ style,
17
+ onRefresh,
18
+ component,
19
+ refreshing,
20
+ placeholder,
21
+ keyboardAware,
22
+ refreshControlProps,
23
+ contentContainerStyle,
24
+ fakeEmpty,
25
+ refreshControl,
26
+ ...props
27
+ } = {
28
+ ...Sections.defaultProps,
29
+ ...sectionsProps,
30
+ }
31
+
32
+ const styles = useStylesFor(Sections.styleRegistryName, style)
33
+
34
+ const renderSeparator = useCallback(() => {
35
+ return <View style={styles?.separator} />
36
+ }, [styles?.separator])
37
+
38
+ const getItemPosition = (section, itemIdx) => {
39
+ const listLength = section?.length || 0
40
+
41
+ const isFirst = itemIdx === 0
42
+ const isLast = itemIdx === listLength - 1
43
+ const isOnly = isFirst && isLast
44
+
45
+ return { isFirst, isLast, isOnly }
46
+ }
47
+
48
+ const getSectionPosition = (data) => {
49
+ const listLength = props.sections?.length || 0
50
+
51
+ const isFirst = data.section.key === props.sections[0].key
52
+ const isLast = data.section.key === props.sections[listLength - 1].key
53
+ const isOnly = isFirst && isLast
54
+
55
+ return { isFirst, isLast, isOnly }
56
+ }
57
+
58
+ const renderSectionHeader = useCallback((data) => {
59
+ if (!props?.renderSectionHeader) return null
60
+
61
+ return props?.renderSectionHeader({ ...data, ...getSectionPosition(data) })
62
+ }, [props?.renderSectionHeader, props?.sections?.length])
63
+
64
+ const renderSectionFooter = useCallback((data) => {
65
+ if (!props?.renderSectionFooter) return null
66
+
67
+ return props?.renderSectionFooter({ ...data, ...getSectionPosition(data) })
68
+ }, [props?.renderSectionFooter, props?.sections?.length])
69
+
70
+ const renderItem = useCallback((data) => {
71
+ if (!props?.renderItem) return null
72
+
73
+ return props?.renderItem({ ...data, ...getItemPosition(data.section?.data, data?.index) })
74
+
75
+ }, [props?.renderItem, props?.sections?.length])
76
+
77
+ const separatorProp = props.separators
78
+ const isEmpty = !props.sections || !props.sections.length
79
+ const separator = !isEmpty && separatorProp == true && renderSeparator
80
+
81
+ const keyboardStyle = useKeyboardPaddingStyle([styles?.content, contentContainerStyle], keyboardAware)
82
+
83
+ return (
84
+ <SectionList
85
+ contentContainerStyle={keyboardStyle}
86
+ showsVerticalScrollIndicator={false}
87
+ // @ts-ignore
88
+ ref={ref}
89
+ ItemSeparatorComponent={separator}
90
+ {...props}
91
+ style={styles?.wrapper}
92
+ refreshControl={
93
+ !!onRefresh && (
94
+ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
95
+ )
96
+ }
97
+ renderItem={renderItem}
98
+ renderSectionHeader={renderSectionHeader}
99
+ renderSectionFooter={renderSectionFooter}
100
+ />
101
+ )
102
+ },
103
+ ) as StyledComponentWithProps<SectionListProps>
104
+
105
+ Sections.styleRegistryName = 'Sections'
106
+ Sections.elements = ['wrapper', 'content', 'separator']
107
+ Sections.rootElement = 'wrapper'
108
+
109
+ Sections.withVariantTypes = <S extends AnyRecord>(styles: S) => {
110
+ return Sections as (props: StyledComponentProps<SectionListProps, typeof styles>) => IJSX
111
+ }
45
112
 
46
- export type SectionListProps<
47
- T = any[],
48
- Data = T extends Array<infer D> ? D : never
49
- > = ReplaceSectionListProps<RNSectionListProps<Data>, Data> &
50
- Omit<ViewProps, 'variants'> & {
51
- separators?: boolean
52
- placeholder?: EmptyPlaceholderProps
53
- styles?: StylesOf<SectionsComposition>
54
- refreshControlProps?: Partial<RefreshControlProps>
55
- fakeEmpty?: boolean
56
- keyboardAware?: boolean
57
- } & ComponentVariants<typeof SectionsPresets>
58
-
59
- const defaultProps: Partial<SectionListProps> = {
113
+ Sections.defaultProps = {
60
114
  keyboardShouldPersistTaps: 'handled',
61
- refreshControlProps: {},
62
115
  keyboardAware: true,
116
+ } as Partial<SectionListProps>
63
117
 
64
- }
65
-
66
- export const Sections = forwardRef<SectionList, SectionListProps>(
67
- (sectionsProps, ref) => {
68
- const {
69
- variants = [],
70
- style,
71
- styles = {},
72
- onRefresh,
73
- component,
74
- refreshing,
75
- placeholder,
76
- keyboardAware,
77
- refreshControlProps,
78
- contentContainerStyle,
79
-
80
- fakeEmpty,
81
- refreshControl,
82
- ...props
83
- } = {
84
- ...defaultProps,
85
- ...sectionsProps,
86
- }
87
-
88
- const variantStyles = useDefaultComponentStyle<'u:Sections', typeof SectionsPresets>('u:Sections', {
89
- variants,
90
- styles,
91
- transform: StyleSheet.flatten,
92
-
93
- })
94
-
95
- const renderSeparator = useCallback(() => {
96
- return (
97
- <View style={variantStyles.separator}></View>
98
- )
99
- }, [variantStyles.separator])
100
-
101
- const getItemPosition = (section, itemIdx) => {
102
- const listLength = section?.length || 0
103
-
104
- const isFirst = itemIdx === 0
105
- const isLast = itemIdx === listLength - 1
106
- const isOnly = isFirst && isLast
107
-
108
- return { isFirst, isLast, isOnly }
109
- }
110
-
111
- const getSectionPosition = (data) => {
112
- const listLength = props.sections?.length || 0
113
-
114
- const isFirst = data.section.key === props.sections[0].key
115
- const isLast = data.section.key === props.sections[listLength - 1].key
116
- const isOnly = isFirst && isLast
117
-
118
- return { isFirst, isLast, isOnly }
119
- }
120
-
121
- const renderSectionHeader = useCallback((data) => {
122
- if (!props?.renderSectionHeader) return null
123
-
124
- return props?.renderSectionHeader({ ...data, ...getSectionPosition(data) })
125
- }, [props?.renderSectionHeader, props?.sections?.length])
126
-
127
- const renderSectionFooter = useCallback((data) => {
128
- if (!props?.renderSectionFooter) return null
129
-
130
- return props?.renderSectionFooter({ ...data, ...getSectionPosition(data) })
131
- }, [props?.renderSectionFooter, props?.sections?.length])
132
-
133
- const renderItem = useCallback((data) => {
134
- if (!props?.renderItem) return null
135
-
136
- return props?.renderItem({ ...data, ...getItemPosition(data.section?.data, data?.index) })
137
-
138
- }, [props?.renderItem, props?.sections?.length])
139
-
140
- const separatorProp = props.separators
141
- const isEmpty = !props.sections || !props.sections.length
142
- const separator = !isEmpty && separatorProp == true && renderSeparator
143
-
144
- const keyboardStyle = useKeyboardPaddingStyle([variantStyles.content, contentContainerStyle], keyboardAware)
145
-
146
- return (
147
- <SectionList
148
- style={[variantStyles.wrapper, style]}
149
- contentContainerStyle={keyboardStyle}
150
- showsVerticalScrollIndicator={false}
151
- // @ts-ignore
152
- ref={ref}
153
- ItemSeparatorComponent={separator}
154
- {...props}
155
- refreshControl={
156
- !!onRefresh && (
157
- <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
158
- )
159
- }
160
- renderItem={renderItem}
161
- renderSectionHeader={renderSectionHeader}
162
- renderSectionFooter={renderSectionFooter}
163
- />
164
- )
165
- },
166
- ) as unknown as (<T = any>(props: SectionListProps<T>) => JSX.Element) & {
167
- defaultProps: Partial<SectionListProps>
168
- }
118
+ MobileStyleRegistry.registerComponent(Sections)
@@ -1,7 +1,2 @@
1
- import { createDefaultVariantFactory, includePresets } from '@codeleap/common'
2
1
 
3
2
  export type SectionsComposition = 'wrapper' |'content' | 'separator'
4
-
5
- const createSectionsStyle = createDefaultVariantFactory<SectionsComposition>()
6
-
7
- export const SectionsPresets = includePresets(style => createSectionsStyle(() => ({ content: style })))
@@ -0,0 +1,39 @@
1
+ import { StyledProp } from '@codeleap/styles'
2
+ import { SectionListRenderItemInfo } from 'react-native'
3
+ import { SectionsComposition } from './styles'
4
+ import { SectionListProps as RNSectionListProps } from 'react-native'
5
+ import { ViewProps } from '../View'
6
+ import { EmptyPlaceholderProps } from '../EmptyPlaceholder'
7
+ import { RefreshControlProps } from '../RefreshControl'
8
+
9
+ export type DataboundSectionListPropsTypes = 'data' | 'renderItem' | 'keyExtractor' | 'getItemLayout' | 'style'
10
+
11
+ export type AugmentedSectionRenderItemInfo<T> = SectionListRenderItemInfo<T> & {
12
+ isFirst: boolean
13
+ isLast: boolean
14
+ isOnly: boolean
15
+ }
16
+
17
+ export type ReplaceSectionListProps<P, T> = Omit<P, DataboundSectionListPropsTypes> & {
18
+ sections: T[]
19
+ keyExtractor?: (item: T, index: number) => string
20
+ renderItem: (data: AugmentedSectionRenderItemInfo<T>) => React.ReactElement
21
+ onRefresh?: () => void
22
+ getItemLayout?: ((data: T, index: number) => { length: number; offset: number; index: number })
23
+ fakeEmpty?: boolean
24
+ }
25
+
26
+ export type SectionListProps<
27
+ T = any[],
28
+ Data = T extends Array<infer D> ? D : never
29
+ > =
30
+ ReplaceSectionListProps<RNSectionListProps<Data>, Data> &
31
+ Omit<ViewProps, 'style'> &
32
+ {
33
+ separators?: boolean
34
+ placeholder?: EmptyPlaceholderProps
35
+ refreshControlProps?: Partial<RefreshControlProps>
36
+ fakeEmpty?: boolean
37
+ keyboardAware?: boolean
38
+ style?: StyledProp<SectionsComposition>
39
+ }