@codeleap/mobile 1.0.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 (103) hide show
  1. package/dist/components/ActivityIndicator.d.ts +13 -0
  2. package/dist/components/ActivityIndicator.js +49 -0
  3. package/dist/components/ActivityIndicator.js.map +1 -0
  4. package/dist/components/Button.d.ts +116 -0
  5. package/dist/components/Button.js +57 -0
  6. package/dist/components/Button.js.map +1 -0
  7. package/dist/components/Checkbox/index.d.ts +14 -0
  8. package/dist/components/Checkbox/index.js +75 -0
  9. package/dist/components/Checkbox/index.js.map +1 -0
  10. package/dist/components/Checkbox/styles.d.ts +48 -0
  11. package/dist/components/Checkbox/styles.js +49 -0
  12. package/dist/components/Checkbox/styles.js.map +1 -0
  13. package/dist/components/Checkbox.d.ts +12 -0
  14. package/dist/components/Checkbox.js +61 -0
  15. package/dist/components/Checkbox.js.map +1 -0
  16. package/dist/components/Drawer.d.ts +23 -0
  17. package/dist/components/Drawer.js +78 -0
  18. package/dist/components/Drawer.js.map +1 -0
  19. package/dist/components/FileInput.d.ts +2 -0
  20. package/dist/components/FileInput.js +28 -0
  21. package/dist/components/FileInput.js.map +1 -0
  22. package/dist/components/Icon.d.ts +13 -0
  23. package/dist/components/Icon.js +47 -0
  24. package/dist/components/Icon.js.map +1 -0
  25. package/dist/components/Image.d.ts +16 -0
  26. package/dist/components/Image.js +48 -0
  27. package/dist/components/Image.js.map +1 -0
  28. package/dist/components/Navigation.d.ts +30 -0
  29. package/dist/components/Navigation.js +126 -0
  30. package/dist/components/Navigation.js.map +1 -0
  31. package/dist/components/RadioInput/index.d.ts +25 -0
  32. package/dist/components/RadioInput/index.js +75 -0
  33. package/dist/components/RadioInput/index.js.map +1 -0
  34. package/dist/components/RadioInput/styles.d.ts +50 -0
  35. package/dist/components/RadioInput/styles.js +45 -0
  36. package/dist/components/RadioInput/styles.js.map +1 -0
  37. package/dist/components/Scroll.d.ts +104 -0
  38. package/dist/components/Scroll.js +73 -0
  39. package/dist/components/Scroll.js.map +1 -0
  40. package/dist/components/Select/index.d.ts +2 -0
  41. package/dist/components/Select/index.js +31 -0
  42. package/dist/components/Select/index.js.map +1 -0
  43. package/dist/components/Slider.d.ts +20 -0
  44. package/dist/components/Slider.js +130 -0
  45. package/dist/components/Slider.js.map +1 -0
  46. package/dist/components/Switch.d.ts +13 -0
  47. package/dist/components/Switch.js +73 -0
  48. package/dist/components/Switch.js.map +1 -0
  49. package/dist/components/Text.d.ts +12 -0
  50. package/dist/components/Text.js +49 -0
  51. package/dist/components/Text.js.map +1 -0
  52. package/dist/components/TextInput.d.ts +146 -0
  53. package/dist/components/TextInput.js +147 -0
  54. package/dist/components/TextInput.js.map +1 -0
  55. package/dist/components/Touchable.d.ts +19 -0
  56. package/dist/components/Touchable.js +62 -0
  57. package/dist/components/Touchable.js.map +1 -0
  58. package/dist/components/View.d.ts +190 -0
  59. package/dist/components/View.js +53 -0
  60. package/dist/components/View.js.map +1 -0
  61. package/dist/components/index.d.ts +16 -0
  62. package/dist/components/index.js +29 -0
  63. package/dist/components/index.js.map +1 -0
  64. package/dist/index.d.ts +2 -0
  65. package/dist/index.js +20 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/modules/fastImage.d.ts +1 -0
  68. package/dist/modules/fastImage.js +10 -0
  69. package/dist/modules/fastImage.js.map +1 -0
  70. package/dist/types/utility.d.ts +2 -0
  71. package/dist/types/utility.js +3 -0
  72. package/dist/types/utility.js.map +1 -0
  73. package/dist/utils/OSAlert.d.ts +31 -0
  74. package/dist/utils/OSAlert.js +89 -0
  75. package/dist/utils/OSAlert.js.map +1 -0
  76. package/dist/utils/styles.d.ts +1 -0
  77. package/dist/utils/styles.js +13 -0
  78. package/dist/utils/styles.js.map +1 -0
  79. package/package.json +32 -0
  80. package/src/components/ActivityIndicator.tsx +37 -0
  81. package/src/components/Button.tsx +61 -0
  82. package/src/components/Checkbox/index.tsx +68 -0
  83. package/src/components/Checkbox/styles.ts +63 -0
  84. package/src/components/FileInput.tsx +6 -0
  85. package/src/components/Icon.tsx +35 -0
  86. package/src/components/Image.tsx +43 -0
  87. package/src/components/Navigation.tsx +125 -0
  88. package/src/components/RadioInput/index.tsx +76 -0
  89. package/src/components/RadioInput/styles.ts +62 -0
  90. package/src/components/Scroll.tsx +87 -0
  91. package/src/components/Select/index.tsx +8 -0
  92. package/src/components/Slider.tsx +198 -0
  93. package/src/components/Switch.tsx +73 -0
  94. package/src/components/Text.tsx +31 -0
  95. package/src/components/TextInput.tsx +206 -0
  96. package/src/components/Touchable.tsx +54 -0
  97. package/src/components/View.tsx +53 -0
  98. package/src/components/index.ts +16 -0
  99. package/src/index.ts +2 -0
  100. package/src/modules/fastImage.ts +2 -0
  101. package/src/types/utility.ts +3 -0
  102. package/src/utils/OSAlert.ts +122 -0
  103. package/src/utils/styles.ts +17 -0
@@ -0,0 +1,61 @@
1
+ import * as React from 'react'
2
+ import { useComponentStyle, ButtonStyles, ComponentVariants, ButtonComposition } from '@codeleap/common';
3
+ import { forwardRef } from 'react'
4
+ import { StylesOf } from '../types/utility';
5
+ import { Text } from './Text';
6
+ import { Touchable, TouchableProps } from './Touchable';
7
+ import { Icon } from './Icon';
8
+ import { ActivityIndicator } from './ActivityIndicator';
9
+ import { IconPlaceholder } from '@codeleap/common';
10
+ import { StyleSheet, TouchableOpacity } from 'react-native';
11
+
12
+
13
+
14
+
15
+ export type ButtonProps = Omit<TouchableProps,'variants'> & ComponentVariants<typeof ButtonStyles> & {
16
+ text?:string
17
+ rightIcon?: IconPlaceholder
18
+ icon?: IconPlaceholder
19
+ styles?: StylesOf<ButtonComposition>
20
+ loading?: boolean
21
+ }
22
+
23
+ export const Button = forwardRef<TouchableOpacity, ButtonProps>( (buttonProps,ref) => {
24
+ const {
25
+ variants = [],
26
+ responsiveVariants = {},
27
+ children,
28
+ icon,
29
+ text,
30
+ loading,
31
+ styles = {},
32
+ onPress,
33
+ rightIcon,
34
+ ...props
35
+ } = buttonProps
36
+
37
+
38
+ const variantStyles = useComponentStyle('Button', {
39
+ variants,
40
+ })
41
+
42
+
43
+ function handlePress(e:Parameters<ButtonProps['onPress']>[0]){
44
+ onPress && onPress(e)
45
+ }
46
+
47
+
48
+ return (
49
+ <Touchable
50
+ style={[variantStyles.wrapper, styles.wrapper]}
51
+ onPress={handlePress}
52
+ ref={ref}
53
+ {...props}
54
+ >
55
+ {loading && <ActivityIndicator style={[variantStyles.loader, styles.loader]} />}
56
+ {!loading && <Icon name={icon} style={StyleSheet.flatten([variantStyles.icon, styles.icon, variantStyles.leftIcon, styles.leftIcon])}/>}
57
+ {children || <Text text={text} style={[variantStyles.text, styles.text]}/>}
58
+ <Icon name={rightIcon} style={StyleSheet.flatten([variantStyles.icon, styles.icon, variantStyles.rightIcon, styles.rightIcon])}/>
59
+ </Touchable>
60
+ )
61
+ })
@@ -0,0 +1,68 @@
1
+ import * as React from 'react'
2
+ import { ComponentVariants, useComponentStyle, StylesOf, Form, useValidate } from '@codeleap/common'
3
+ import { ComponentPropsWithRef, forwardRef, ReactNode } from 'react'
4
+ import { Switch as NativeCheckbox } from 'react-native'
5
+ import { InputLabel, FormError } from '../TextInput'
6
+ import { View } from '../View'
7
+ import { Touchable } from '../Touchable'
8
+ import {
9
+ MobileCheckboxStyles as CheckboxStyles, MobileCheckboxComposition as CheckboxComposition
10
+ } from './styles'
11
+ export * from './styles'
12
+
13
+ type NativeCheckboxProps = Omit<
14
+ ComponentPropsWithRef<typeof NativeCheckbox>,
15
+ 'thumbColor'|'trackColor'
16
+ >
17
+ type CheckboxProps = NativeCheckboxProps & {
18
+ variants?: ComponentVariants<typeof CheckboxStyles>['variants']
19
+ label?: ReactNode
20
+ styles?: StylesOf<CheckboxComposition>
21
+ validate?: Form.ValidatorFunction | string
22
+ }
23
+
24
+ export const Checkbox = forwardRef<NativeCheckbox,CheckboxProps>((checkboxProps,ref) => {
25
+ const {
26
+ variants = [],
27
+ style = {},
28
+ styles = {},
29
+ label,
30
+ value,
31
+ onValueChange,
32
+ validate,
33
+ ...props
34
+ } = checkboxProps
35
+
36
+ const variantStyles = useComponentStyle('Checkbox', {
37
+ // @ts-ignore
38
+ variants,
39
+ })
40
+
41
+ const {error, showError} = useValidate(value,validate)
42
+
43
+
44
+ function getStyles(key:CheckboxComposition){
45
+ return [
46
+ variantStyles[key],
47
+ variantStyles[key],
48
+ key === 'wrapper' ? style : {},
49
+ value ? variantStyles[key + ':checked'] : {},
50
+ value ? styles[key + ':checked'] : {},
51
+ showError ? variantStyles[key + ':error'] : {},
52
+ showError ? styles[key + ':error'] : {},
53
+ checkboxProps.disabled ? variantStyles[key + ':disabled'] : {},
54
+ checkboxProps.disabled ? styles[key + ':disabled'] : {},
55
+ ]
56
+ }
57
+
58
+ return <View style={getStyles('wrapper')} {...props}>
59
+ <Touchable style={getStyles('input')} onPress={() => onValueChange(!value)}>
60
+ <View style={getStyles('checkmarkWrapper')}>
61
+ <View style={getStyles('checkmark')}/>
62
+ </View>
63
+ <InputLabel label={label} style={getStyles('label')}/>
64
+
65
+ </Touchable>
66
+ <FormError message={error.message} style={getStyles('error')} />
67
+ </View>
68
+ })
@@ -0,0 +1,63 @@
1
+ import {createDefaultVariantFactory, includePresets} from '@codeleap/common'
2
+
3
+ type CheckboxParts = 'wrapper' | 'label' | 'input' | 'checkmark' | 'checkmarkWrapper' | 'error'
4
+
5
+ export type MobileCheckboxComposition = CheckboxParts | `${CheckboxParts}:checked` | `${CheckboxParts}:disabled` | `${CheckboxParts}:error`;
6
+ const createCheckboxStyle = createDefaultVariantFactory<MobileCheckboxComposition>()
7
+
8
+ const presets = includePresets((styles) => createCheckboxStyle(() => ({ wrapper: styles })))
9
+
10
+ export const MobileCheckboxStyles = {
11
+ ...presets,
12
+ default: createCheckboxStyle((theme) => {
13
+ const size = theme.typography.baseFontSize * 1.2
14
+
15
+ const markHeight = size * 0.5
16
+ const markWidth = size * 0.25
17
+
18
+ const translateX = -(markWidth/2)
19
+ const translateY = -(markHeight/2)
20
+ return {
21
+ wrapper: {
22
+
23
+ },
24
+ input: {
25
+ flexDirection: 'row',
26
+ ...theme.presets.alignCenter,
27
+ borderRadius: theme.borderRadius.small
28
+ },
29
+ label: {
30
+ ...theme.spacing.marginLeft(0.5),
31
+ },
32
+
33
+ checkmark: {
34
+ position: 'absolute',
35
+ top: '40%',
36
+ left: '50%',
37
+
38
+ height: markHeight,
39
+ width: markWidth,
40
+ transform: [{translateX}, {translateY}, {rotate: '45deg'},]
41
+ },
42
+ "checkmark:checked": {
43
+ ...theme.border.white({
44
+ width: 2,
45
+ directions: ['right','bottom']
46
+ }),
47
+ },
48
+ checkmarkWrapper: {
49
+ position: 'relative',
50
+ width: size,
51
+ height: size,
52
+ ...theme.border.gray(1)
53
+ },
54
+ "checkmarkWrapper:checked": {
55
+ backgroundColor: theme.colors.primary
56
+ },
57
+ error: {
58
+ color: theme.colors.negative
59
+ }
60
+ }
61
+ }),
62
+
63
+ }
@@ -0,0 +1,6 @@
1
+ import * as React from 'react'
2
+ import { Text } from 'react-native'
3
+
4
+ export const FileInput = React.forwardRef(() => {
5
+ return <Text >Not implemented</Text>
6
+ })
@@ -0,0 +1,35 @@
1
+ import * as React from 'react'
2
+ import { ComponentVariants, IconPlaceholder, IconStyles, useComponentStyle, useStyle } from '@codeleap/common'
3
+ import { StyleSheet } from 'react-native'
4
+
5
+ export type IconProps = {
6
+ name:IconPlaceholder
7
+ style?: {
8
+ color: string
9
+ size?:string|number
10
+ width?:string|number
11
+ height?:string|number
12
+ }
13
+ variants?: ComponentVariants<typeof IconStyles>['variants']
14
+ }
15
+
16
+ export const Icon:React.FC<IconProps> = ({name, style, variants}) => {
17
+ const {Theme} = useStyle()
18
+
19
+ if (!name) return null
20
+
21
+ const Component = Theme?.icons?.[name]
22
+
23
+ const {logger} = useStyle()
24
+ const variantStyles = useComponentStyle('Icon', {
25
+ variants,
26
+ styles: {
27
+ icon: StyleSheet.flatten([style]),
28
+ }
29
+ })
30
+ if (!Component) {
31
+ logger.warn('Icon', `No icon found in theme for name "${name}"`, 'Component')
32
+ return null
33
+ }
34
+ return <Component style={variantStyles.icon}/>
35
+ }
@@ -0,0 +1,43 @@
1
+ import * as React from 'react'
2
+ import { ComponentVariants, ImageStyles, useComponentStyle } from "@codeleap/common"
3
+ import { ComponentPropsWithoutRef } from "react"
4
+ import { Image as NativeImage } from 'react-native'
5
+ import {FastImage} from '../modules/fastImage'
6
+
7
+ type NativeImageProps = ComponentPropsWithoutRef<typeof NativeImage>
8
+ export type ImageProps = Omit<NativeImageProps, 'source'> & {
9
+ variants?: ComponentVariants<typeof ImageStyles>['variants']
10
+ fast?: boolean
11
+ source: NativeImageProps['source'] & {
12
+ priority?: keyof typeof FastImage.priority
13
+ }
14
+ resizeMode?: keyof typeof FastImage.resizeMode
15
+ }
16
+
17
+ export const Image:React.FC<ImageProps> = (props) => {
18
+ const {
19
+ variants,
20
+ style,
21
+ fast,
22
+ resizeMode,
23
+ resizeMethod,
24
+ ...imageProps
25
+ } = props
26
+
27
+ const variantStyles = useComponentStyle('Image', {variants})
28
+
29
+ const styles = [variantStyles.wrapper, style]
30
+
31
+
32
+ if(fast){
33
+ return <FastImage
34
+ style={styles}
35
+ resizeMode={ FastImage.resizeMode[resizeMode || 'contain']}
36
+ {...imageProps}
37
+ />
38
+ }
39
+ return <NativeImage
40
+ style={styles}
41
+ {...imageProps}
42
+ />
43
+ }
@@ -0,0 +1,125 @@
1
+ // @ts-nocheck
2
+ import * as React from 'react'
3
+ import { RouteConfig } from '@react-navigation/native'
4
+ import { createNativeStackNavigator, NativeStackScreenProps } from '@react-navigation/native-stack'
5
+ import { AnyFunction, EnhancedTheme, IconPlaceholder, useStyle } from '@codeleap/common'
6
+ import { createDrawerNavigator } from '@react-navigation/drawer'
7
+ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
8
+ import { Icon } from './Icon'
9
+ import { Paths } from '@codeleap/common/dist/types/pathMapping'
10
+
11
+ export type AppScenes = {
12
+ [x:string] : {
13
+ [y:string] : AnyFunction | ( Partial<Pick<RouteConfig<any, any, any, any, any>, 'options'>> & {
14
+ render: AnyFunction,
15
+ icon?: any
16
+ })
17
+ }
18
+ }
19
+
20
+ const parseModulePages = (pageModule:string, [pageName, Component]) => {
21
+ const name = `${pageModule}.${pageName}`
22
+
23
+ let props = {
24
+ name,
25
+ key: name,
26
+ options: {
27
+ title: pageName,
28
+ },
29
+ component: null,
30
+ }
31
+
32
+ switch (typeof Component){
33
+ case 'function':
34
+ props.component = Component
35
+ case 'object':
36
+ props = {
37
+ ...props,
38
+ ...Component,
39
+ }
40
+ if (typeof Component.default === 'function'){
41
+ props.component = Component.default
42
+ }
43
+
44
+ if (Component.render){
45
+ props.component = typeof Component.render === 'function' ? Component.render : Component?.render?.default
46
+ }
47
+
48
+ default:
49
+ break
50
+ }
51
+
52
+ return props
53
+ }
54
+
55
+ type FlattenScenesArgs = {
56
+ scenes:AppScenes,
57
+ Theme: EnhancedTheme<any>
58
+ }
59
+ const flattenScenes = ({
60
+ scenes,
61
+ Theme,
62
+ }:FlattenScenesArgs) => {
63
+
64
+ return Object.entries(scenes).reduce((acc, [pageModule, pages]) => {
65
+ const thisModulePages = {}
66
+ for (const pageData of Object.entries(pages)){
67
+ const parsedData = parseModulePages(pageModule, pageData)
68
+
69
+ thisModulePages[parsedData.name] = parsedData
70
+ }
71
+ return {...acc, ...thisModulePages}
72
+ }, {})
73
+ }
74
+
75
+ const Navigators = {
76
+ drawer: createDrawerNavigator(),
77
+ stack: createNativeStackNavigator(),
78
+ tab: createBottomTabNavigator(),
79
+ }
80
+ type NavigationType = keyof typeof Navigators
81
+ type NavigationProps<T extends NavigationType> = {
82
+ scenes: AppScenes
83
+ type: T
84
+ } & React.ComponentPropsWithoutRef<(typeof Navigators)[T]['Navigator']>
85
+
86
+
87
+ export const Navigation = <T extends NavigationType, P extends NavigationProps<T> = NavigationProps<T>>({type, scenes, ...props}:P) => {
88
+ const Navigator:(typeof Navigators)[T] = Navigators[type]
89
+ const { Theme } = useStyle()
90
+ const flatScenes = flattenScenes({
91
+ Theme,
92
+ scenes,
93
+ })
94
+
95
+ const otherProps = props as any
96
+ // @ts-ignore
97
+ const screenOptions:P['screenOptions'] = ({route, navigation}) => {
98
+ const propOptions = typeof (otherProps?.screenOptions || {}) === 'function' ?
99
+ otherProps.screenOptions({route, navigation}) :
100
+ otherProps?.screenOptions
101
+
102
+ return {
103
+ ...propOptions,
104
+ tabBarIcon: (style) => {
105
+ if (flatScenes?.[route.name]?.icon){
106
+ return <Icon name={flatScenes?.[route.name]?.icon} style={style}/>
107
+ }
108
+ return null
109
+ },
110
+ }
111
+ }
112
+
113
+ return <Navigator.Navigator {...otherProps} screenOptions={screenOptions} >
114
+ {
115
+ Object.values(flatScenes).map((props) => <Navigator.Screen {...(props as any)}/>)
116
+ }
117
+ </Navigator.Navigator>
118
+
119
+ }
120
+ export type NavigationScreenProps<S extends AppScenes, T extends NativeStackScreenProps<any, any> = NativeStackScreenProps<any, any>> = Omit<T, 'navigation'> & {
121
+ navigation: Omit<T['navigation'],'navigate'> & {
122
+ navigate: (to: Exclude<Paths<S, 1>, keyof S>) => void
123
+ }
124
+
125
+ }
@@ -0,0 +1,76 @@
1
+ import * as React from 'react'
2
+ import { ReactNode, useRef, ComponentPropsWithoutRef } from 'react'
3
+ import { v4 } from 'uuid'
4
+
5
+ import {Text } from '../Text'
6
+ import { Touchable } from '../Touchable'
7
+ import { ComponentVariants, StylesOf, useComponentStyle } from '@codeleap/common'
8
+ import { View } from '../View'
9
+ import { MobileRadioInputStyles, MobileRadioInputComposition} from './styles'
10
+
11
+ export * from './styles'
12
+
13
+ type RadioItem<T extends unknown = any> = {
14
+ value: T,
15
+ label: ReactNode
16
+ }
17
+
18
+ const getRadioStyle = (props) => useComponentStyle('RadioInput', props)
19
+
20
+ export type RadioButtonProps = Omit<ComponentPropsWithoutRef<typeof Touchable>, 'style'> & {
21
+ item: RadioItem
22
+ select: () => void
23
+ style: StylesOf<MobileRadioInputComposition>
24
+ checked: boolean
25
+ }
26
+
27
+ export type RadioGroupProps<T> = {
28
+ options: RadioItem<T>[]
29
+ value: T
30
+ onValueChange(value:T):void
31
+ label:ReactNode
32
+ styles?: StylesOf<MobileRadioInputComposition>
33
+ } & ComponentVariants<typeof MobileRadioInputStyles>
34
+
35
+
36
+ export const RadioButton:React.FC<RadioButtonProps> = ({item, select, style, checked, ...props}) => {
37
+
38
+ return <Touchable onPress={select} style={style.itemWrapper} >
39
+ <View style={[
40
+ style.button,
41
+ checked && style['button:checked'],
42
+ ]}>
43
+ <View style={[
44
+ style['buttonMark'],
45
+ checked && style['buttonMark:checked'],
46
+ ]} />
47
+ </View>
48
+ {typeof item.label === 'string' ? <Text text={item.label} style={style.text}/> : item.label }
49
+ </Touchable>
50
+ }
51
+
52
+
53
+ export const RadioGroup = <T extends unknown>(radioGroupProps:RadioGroupProps<T>) => {
54
+ const {options, value, onValueChange, label, responsiveVariants, variants, styles} = radioGroupProps
55
+
56
+ const radioStyle = getRadioStyle({
57
+ responsiveVariants,
58
+ variants,
59
+ styles,
60
+ })
61
+ return <View style={radioStyle.wrapper}>
62
+ {typeof label === 'string' ? <Text text={label}/> : label }
63
+ <View style={radioStyle.listWrapper}>
64
+ {
65
+ options?.map((item, idx) => <RadioButton
66
+ item={item}
67
+ key={idx}
68
+ style={radioStyle}
69
+
70
+ checked={value === item.value}
71
+ select={() => onValueChange(item.value)}
72
+ />)
73
+ }
74
+ </View>
75
+ </View>
76
+ }
@@ -0,0 +1,62 @@
1
+ import { createDefaultVariantFactory, RadioInputStyles } from '@codeleap/common';
2
+ type RadioParts = 'button' | 'itemWrapper' | 'text' | 'buttonMark'
3
+
4
+ type RadioGroupParts = 'label' |'wrapper' |'list'
5
+
6
+ export type MobileRadioInputComposition = `${RadioParts}:checked` | RadioParts | RadioGroupParts
7
+
8
+ const createRadioStyle = createDefaultVariantFactory<MobileRadioInputComposition>()
9
+
10
+ const defaultStyles = RadioInputStyles.default
11
+
12
+ export const MobileRadioInputStyles = {
13
+ ...RadioInputStyles,
14
+ default: createRadioStyle((theme) => {
15
+ const style = defaultStyles(theme)
16
+
17
+ const itemHeight = theme.typography.baseFontSize * 1.2
18
+ const markHeight = itemHeight / 2
19
+ const translateX = -(markHeight/2)
20
+ const translateY = -(markHeight/2)
21
+ return {
22
+ ...style,
23
+ itemWrapper: {
24
+ ...style.itemWrapper,
25
+ },
26
+ button: {
27
+ height: itemHeight,
28
+ width: itemHeight,
29
+ ...theme.border.primary(1),
30
+ borderRadius: theme.borderRadius.large,
31
+
32
+ position: 'relative',
33
+ ...theme.spacing.marginRight(1),
34
+
35
+ },
36
+ 'buttonMark': {
37
+ backgroundColor: theme.colors.primary,
38
+ position: 'absolute',
39
+ left: '50%',
40
+ top: '50%',
41
+ height: markHeight,
42
+ width: markHeight,
43
+
44
+ transform: [{translateX},{translateY}],
45
+ borderRadius: theme.borderRadius.large,
46
+ opacity: 0
47
+ },
48
+ 'buttonMark:checked': {
49
+ opacity: 1
50
+ },
51
+ }
52
+ }),
53
+ square: createRadioStyle(() => ({
54
+ 'buttonMark': {
55
+ borderRadius: 0,
56
+ },
57
+ button: {
58
+ borderRadius: 0,
59
+
60
+ },
61
+ })),
62
+ }
@@ -0,0 +1,87 @@
1
+ import * as React from 'react'
2
+ import { forwardRef, useState } from 'react'
3
+ import { deepEqual, onUpdate, useComponentStyle, usePrevious, useStyle } from '@codeleap/common'
4
+ import { KeyboardAwareScrollViewProps, KeyboardAwareScrollView as KBDView} from 'react-native-keyboard-aware-scroll-view'
5
+ import { RefreshControl, ScrollView } from 'react-native'
6
+ import { ViewProps } from './View'
7
+
8
+
9
+ export type ScrollProps = KeyboardAwareScrollViewProps & ViewProps & {
10
+ onRefresh?:() => void
11
+ refreshTimeout?: number
12
+ changeData?:any
13
+ }
14
+
15
+ const KeyboardAwareScrollView = KBDView as unknown as React.ForwardRefExoticComponent<
16
+ ViewProps &
17
+ {
18
+ refreshControl?: JSX.Element
19
+ ref?: ScrollView
20
+
21
+ }
22
+ >
23
+
24
+
25
+ export const Scroll = forwardRef<ScrollView, ScrollProps>((scrollProps, ref) => {
26
+ const {
27
+ variants = [],
28
+ style,
29
+ refreshTimeout = 3000,
30
+ children,
31
+ changeData,
32
+ ...props
33
+ } = scrollProps
34
+ const hasRefresh = !!props.onRefresh
35
+ const [refreshing, setRefreshing] = useState(false)
36
+
37
+ const timer = React.useRef(null)
38
+ const previousData = usePrevious(changeData)
39
+
40
+ const onRefresh = () => {
41
+ if(timer.current){
42
+ clearTimeout(timer.current)
43
+ }
44
+
45
+ setRefreshing(true)
46
+
47
+ props.onRefresh()
48
+
49
+ timer.current = setTimeout(() => {
50
+ setRefreshing(false)
51
+ }, refreshTimeout)
52
+
53
+ }
54
+ onUpdate(() => {
55
+ if(refreshing && !deepEqual(previousData, changeData)){
56
+ setRefreshing(false)
57
+ if(timer.current){
58
+ clearTimeout(timer.current)
59
+ }
60
+ }
61
+ },[refreshing, changeData])
62
+ const {
63
+ Theme
64
+ } = useStyle()
65
+
66
+ const variantStyles = useComponentStyle('View', {
67
+ variants
68
+ })
69
+
70
+ return (
71
+
72
+ <KeyboardAwareScrollView
73
+ style={[Theme.presets.full, variantStyles.wrapper, style]}
74
+ ref={ref as unknown as ScrollView}
75
+ {...props}
76
+ refreshControl={
77
+ hasRefresh &&
78
+ <RefreshControl
79
+ refreshing={refreshing}
80
+ onRefresh={onRefresh}
81
+ />
82
+ }
83
+ >
84
+ { children }
85
+ </KeyboardAwareScrollView>
86
+ )
87
+ })
@@ -0,0 +1,8 @@
1
+ import * as React from 'react'
2
+ import { View } from "../View"
3
+
4
+ export const Select:React.FC = () => {
5
+ return <View >
6
+
7
+ </View>
8
+ }