@codeleap/mobile 1.2.1 → 1.3.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.
- package/dist/components/Animated.d.ts +103 -0
- package/dist/components/Animated.js +55 -0
- package/dist/components/Animated.js.map +1 -0
- package/dist/components/Button.d.ts +2 -8
- package/dist/components/Button.js +2 -1
- package/dist/components/Button.js.map +1 -1
- package/dist/components/FileInput.d.ts +19 -2
- package/dist/components/FileInput.js +89 -4
- package/dist/components/FileInput.js.map +1 -1
- package/dist/components/Image.d.ts +2 -2
- package/dist/components/Image.js.map +1 -1
- package/dist/components/Modal/index.d.ts +24 -0
- package/dist/components/Modal/index.js +116 -0
- package/dist/components/Modal/index.js.map +1 -0
- package/dist/components/Modal/styles.d.ts +62 -0
- package/dist/components/Modal/styles.js +62 -0
- package/dist/components/Modal/styles.js.map +1 -0
- package/dist/components/Overlay.d.ts +16 -0
- package/dist/components/Overlay.js +68 -0
- package/dist/components/Overlay.js.map +1 -0
- package/dist/components/Scroll.d.ts +1 -95
- package/dist/components/TextInput.js +22 -18
- package/dist/components/TextInput.js.map +1 -1
- package/dist/components/Touchable.d.ts +8 -14
- package/dist/components/Touchable.js +10 -12
- package/dist/components/Touchable.js.map +1 -1
- package/dist/components/View.d.ts +12 -10
- package/dist/components/View.js +2 -4
- package/dist/components/View.js.map +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +3 -0
- package/dist/components/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/cropPicker.d.ts +1 -0
- package/dist/modules/cropPicker.js +10 -0
- package/dist/modules/cropPicker.js.map +1 -0
- package/dist/modules/documentPicker.d.ts +1 -0
- package/dist/modules/documentPicker.js +10 -0
- package/dist/modules/documentPicker.js.map +1 -0
- package/dist/utils/styles.js.map +1 -1
- package/package.json +6 -3
- package/src/components/Animated.tsx +31 -0
- package/src/components/Button.tsx +2 -1
- package/src/components/FileInput.tsx +67 -4
- package/src/components/Image.tsx +3 -3
- package/src/components/Modal/index.tsx +143 -0
- package/src/components/Modal/styles.ts +122 -0
- package/src/components/Overlay.tsx +72 -0
- package/src/components/TextInput.tsx +28 -22
- package/src/components/Touchable.tsx +20 -23
- package/src/components/View.tsx +5 -15
- package/src/components/index.ts +4 -0
- package/src/index.ts +2 -1
- package/src/modules/documentPicker.ts +2 -0
- package/src/utils/styles.ts +2 -2
package/dist/index.js
CHANGED
|
@@ -13,8 +13,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
14
|
};
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.OSAlert = void 0;
|
|
16
|
+
exports.posed = exports.OSAlert = void 0;
|
|
17
17
|
__exportStar(require("./components"), exports);
|
|
18
18
|
var OSAlert_1 = require("./utils/OSAlert");
|
|
19
19
|
Object.defineProperty(exports, "OSAlert", { enumerable: true, get: function () { return __importDefault(OSAlert_1).default; } });
|
|
20
|
+
var react_native_pose_1 = require("react-native-pose");
|
|
21
|
+
Object.defineProperty(exports, "posed", { enumerable: true, get: function () { return __importDefault(react_native_pose_1).default; } });
|
|
20
22
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA4B;AAC5B,2CAAmD;AAA3C,mHAAA,OAAO,OAAW"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA4B;AAC5B,2CAAmD;AAA3C,mHAAA,OAAO,OAAW;AAC1B,uDAAkD;AAA1C,2HAAA,OAAO,OAAS"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ImagePicker } from 'react-native-image-crop-picker';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ImagePicker = void 0;
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
var react_native_image_crop_picker_1 = require("react-native-image-crop-picker");
|
|
9
|
+
Object.defineProperty(exports, "ImagePicker", { enumerable: true, get: function () { return __importDefault(react_native_image_crop_picker_1).default; } });
|
|
10
|
+
//# sourceMappingURL=cropPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cropPicker.js","sourceRoot":"","sources":["../../src/modules/cropPicker.ts"],"names":[],"mappings":";;;;;;AAAA,aAAa;AACb,iFAAqE;AAA7D,8IAAA,OAAO,OAAe"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as DocumentPicker } from 'react-native-document-picker';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DocumentPicker = void 0;
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
var react_native_document_picker_1 = require("react-native-document-picker");
|
|
9
|
+
Object.defineProperty(exports, "DocumentPicker", { enumerable: true, get: function () { return __importDefault(react_native_document_picker_1).default; } });
|
|
10
|
+
//# sourceMappingURL=documentPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentPicker.js","sourceRoot":"","sources":["../../src/modules/documentPicker.ts"],"names":[],"mappings":";;;;;;AAAA,cAAc;AACd,6EAAsE;AAA9D,+IAAA,OAAO,OAAkB"}
|
package/dist/utils/styles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/utils/styles.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/utils/styles.ts"],"names":[],"mappings":";;;AAAA,2CAA4C;AAC5C,6CAA0C;AAE1C,SAAgB,YAAY;IAEjB,IAAA,MAAM,GAAI,IAAA,iBAAQ,GAAE,OAAd,CAAc;IAG3B,OAAO,UAAC,IAAI,EAAC,MAAM;QACf,MAAM,CAAC,KAAK,CAAC,IAAI,CACb,IAAI,EACJ,IAAI,CAAC,SAAS,CAAC,yBAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EACnD,kBAAkB,CACrB,CAAA;IACL,CAAC,CAAA;AAEL,CAAC;AAbD,oCAaC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeleap/mobile",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"repository": "git@github.com:codeleap-uk/codeleap-lib.git",
|
|
6
6
|
"author": "Paulo Henrique De Souza <paulosouza300272@gmail.com>",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "tsc --build",
|
|
16
|
-
"lint": "./node_modules/.bin/eslint -c .eslintrc.js \"./src/**/*.{ts,tsx,js,jsx}\""
|
|
16
|
+
"lint": "./node_modules/.bin/eslint -c .eslintrc.js \"./src/**/*.{ts,tsx,js,jsx}\"",
|
|
17
|
+
"publish": "npm publish"
|
|
17
18
|
},
|
|
18
19
|
"peerDependencies": {
|
|
19
20
|
"@codeleap/common": "*",
|
|
@@ -27,6 +28,8 @@
|
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
30
|
"@miblanchard/react-native-slider": "^2.1.0",
|
|
30
|
-
"react-native-
|
|
31
|
+
"react-native-animatable": "^1.3.3",
|
|
32
|
+
"react-native-keyboard-aware-scroll-view": "^0.9.5",
|
|
33
|
+
"react-native-pose": "^0.9.1"
|
|
31
34
|
}
|
|
32
35
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { onUpdate } from '@codeleap/common'
|
|
2
|
+
import React, { useRef } from 'react'
|
|
3
|
+
|
|
4
|
+
import posed from 'react-native-pose'
|
|
5
|
+
import {Touchable} from './Touchable'
|
|
6
|
+
import {View} from './View'
|
|
7
|
+
const Components = {
|
|
8
|
+
Touchable,
|
|
9
|
+
View
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const PosedComponents = Object.fromEntries(Object.entries(Components).map(([key,Render]) => [key, posed(Render)]))
|
|
14
|
+
|
|
15
|
+
type AnimatedComponents = typeof Components
|
|
16
|
+
type CP = keyof AnimatedComponents
|
|
17
|
+
|
|
18
|
+
type AnimatedProps<T extends CP, CFG = Record<string,any>> = {
|
|
19
|
+
component: T
|
|
20
|
+
config: CFG
|
|
21
|
+
pose: keyof CFG
|
|
22
|
+
initialPose?: keyof CFG
|
|
23
|
+
} & Omit<Parameters<AnimatedComponents[T]>[0],'component'>
|
|
24
|
+
|
|
25
|
+
export const Animated = <T extends CP, CFG = any>({config,component, ...props}:AnimatedProps<T, CFG>) => {
|
|
26
|
+
|
|
27
|
+
const Component = useRef(PosedComponents[component](config)).current
|
|
28
|
+
|
|
29
|
+
return <Component {...props} />
|
|
30
|
+
}
|
|
31
|
+
|
|
@@ -54,7 +54,8 @@ export const Button = forwardRef<TouchableOpacity, ButtonProps>( (buttonProps,re
|
|
|
54
54
|
>
|
|
55
55
|
{loading && <ActivityIndicator style={[variantStyles.loader, styles.loader]} />}
|
|
56
56
|
{!loading && <Icon name={icon} style={StyleSheet.flatten([variantStyles.icon, styles.icon, variantStyles.leftIcon, styles.leftIcon])}/>}
|
|
57
|
-
{
|
|
57
|
+
{text ? <Text text={text} style={[variantStyles.text, styles.text]}/> : null}
|
|
58
|
+
{children}
|
|
58
59
|
<Icon name={rightIcon} style={StyleSheet.flatten([variantStyles.icon, styles.icon, variantStyles.rightIcon, styles.rightIcon])}/>
|
|
59
60
|
</Touchable>
|
|
60
61
|
)
|
|
@@ -1,6 +1,69 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import React, { forwardRef, useImperativeHandle, useRef } from 'react'
|
|
2
|
+
import { DocumentPicker } from '../modules/documentPicker'
|
|
3
|
+
import { ComponentVariants, FileInputComposition, FileInputStyles, IconPlaceholder, MobileInputFile, useComponentStyle, useStyle} from '@codeleap/common'
|
|
4
|
+
import { StylesOf } from '../types/utility'
|
|
5
|
+
import { Button, ButtonProps } from './Button'
|
|
6
|
+
import { View } from './View'
|
|
7
|
+
import { InputLabel } from './TextInput'
|
|
3
8
|
|
|
4
|
-
export
|
|
5
|
-
|
|
9
|
+
export type FileInputRef = {
|
|
10
|
+
openFilePicker: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type FileInputProps = {
|
|
14
|
+
label?: string;
|
|
15
|
+
iconName?: IconPlaceholder
|
|
16
|
+
styles?: StylesOf<FileInputComposition>;
|
|
17
|
+
mode: 'hidden' | 'button'
|
|
18
|
+
variants?: ComponentVariants<typeof FileInputStyles>['variants']
|
|
19
|
+
onFileSelect(files:MobileInputFile[]): void
|
|
20
|
+
options?: DocumentPicker.DocumentPickerOptions
|
|
21
|
+
buttonProps?: ButtonProps
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const FileInput: React.FC<FileInputProps> = forwardRef<FileInputRef, FileInputProps>((fileInputProps,ref) => {
|
|
25
|
+
const {mode = 'hidden', onFileSelect, iconName, styles, label, variants, options, buttonProps} = fileInputProps
|
|
26
|
+
|
|
27
|
+
const [file, setFile] = React.useState(null)
|
|
28
|
+
|
|
29
|
+
const {logger} = useStyle()
|
|
30
|
+
|
|
31
|
+
const openFilePicker = async () => {
|
|
32
|
+
try {
|
|
33
|
+
let files = await DocumentPicker.pick(options)
|
|
34
|
+
if(!Array.isArray(files)){
|
|
35
|
+
files = [files]
|
|
36
|
+
}
|
|
37
|
+
setFile(files)
|
|
38
|
+
onFileSelect(files.map((file) => ({preview: file, file})))
|
|
39
|
+
} catch (err) {
|
|
40
|
+
if (DocumentPicker.isCancel(err)) {
|
|
41
|
+
logger.log('User cancelled the picker.', null, 'Component')
|
|
42
|
+
} else {
|
|
43
|
+
throw err
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const variantStyles = useComponentStyle('FileInput', {
|
|
49
|
+
styles,
|
|
50
|
+
variants,
|
|
51
|
+
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
useImperativeHandle(ref, () => ({
|
|
56
|
+
openFilePicker
|
|
57
|
+
}))
|
|
58
|
+
|
|
59
|
+
const filenames = file ? file.map((f) => f.name) : ''
|
|
60
|
+
if(mode === 'button'){
|
|
61
|
+
return (<View style={variantStyles.wrapper}>
|
|
62
|
+
<InputLabel label={label} style={variantStyles.label}/>
|
|
63
|
+
<Button onPress={() => openFilePicker()} text={filenames } icon={ iconName || 'fileInputButton' as IconPlaceholder} variants={filenames ? '' : 'icon' } {...buttonProps}/>
|
|
64
|
+
</View>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return null
|
|
6
69
|
})
|
package/src/components/Image.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
|
-
import { ComponentVariants, ImageStyles, useComponentStyle } from "@codeleap/common"
|
|
2
|
+
import { ComponentVariants, ImageStyles, MobileInputFile, useComponentStyle } from "@codeleap/common"
|
|
3
3
|
import { ComponentPropsWithoutRef } from "react"
|
|
4
4
|
import { Image as NativeImage } from 'react-native'
|
|
5
5
|
import {FastImage} from '../modules/fastImage'
|
|
@@ -10,7 +10,7 @@ export type ImageProps = Omit<NativeImageProps, 'source'> & {
|
|
|
10
10
|
fast?: boolean
|
|
11
11
|
source: NativeImageProps['source'] & {
|
|
12
12
|
priority?: keyof typeof FastImage.priority
|
|
13
|
-
}
|
|
13
|
+
} | MobileInputFile | string
|
|
14
14
|
resizeMode?: keyof typeof FastImage.resizeMode
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -38,6 +38,6 @@ export const Image:React.FC<ImageProps> = (props) => {
|
|
|
38
38
|
}
|
|
39
39
|
return <NativeImage
|
|
40
40
|
style={styles}
|
|
41
|
-
{...imageProps}
|
|
41
|
+
{...(imageProps as any)}
|
|
42
42
|
/>
|
|
43
43
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
View,
|
|
4
|
+
ViewProps,
|
|
5
|
+
AnimatedView
|
|
6
|
+
} from '../View'
|
|
7
|
+
import { Button, ButtonProps } from '../Button'
|
|
8
|
+
import { Scroll } from '../Scroll'
|
|
9
|
+
import { capitalize, ComponentVariants, IconPlaceholder, onUpdate, useComponentStyle, useStyle } from '@codeleap/common'
|
|
10
|
+
import { MobileModalComposition, MobileModalStyles, MobileModalParts } from './styles'
|
|
11
|
+
import { StyleSheet } from 'react-native'
|
|
12
|
+
import { StylesOf } from '../../types/utility'
|
|
13
|
+
|
|
14
|
+
import { Touchable } from '../Touchable'
|
|
15
|
+
import { Text } from '../Text'
|
|
16
|
+
import { Animated } from '../Animated'
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export * from './styles'
|
|
20
|
+
|
|
21
|
+
export type ModalProps = Omit<ViewProps, 'variants'|'styles'> & {
|
|
22
|
+
variants?: ComponentVariants<typeof MobileModalStyles>['variants']
|
|
23
|
+
styles?: StylesOf<MobileModalComposition>
|
|
24
|
+
dismissOnBackdrop?: boolean
|
|
25
|
+
buttonProps?: ButtonProps
|
|
26
|
+
accessible?:boolean
|
|
27
|
+
showClose?: boolean
|
|
28
|
+
closable?: boolean
|
|
29
|
+
footer?: React.ReactNode
|
|
30
|
+
title?: React.ReactNode;
|
|
31
|
+
debugName?: string
|
|
32
|
+
closeIconName?: IconPlaceholder
|
|
33
|
+
visible: boolean
|
|
34
|
+
toggle: () => void
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const Modal:React.FC<ModalProps> = (modalProps) => {
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
variants = [],
|
|
41
|
+
styles = { },
|
|
42
|
+
style,
|
|
43
|
+
visible,
|
|
44
|
+
showClose,
|
|
45
|
+
closable = true,
|
|
46
|
+
title,
|
|
47
|
+
footer,
|
|
48
|
+
children,
|
|
49
|
+
toggle,
|
|
50
|
+
dismissOnBackdrop = true,
|
|
51
|
+
closeIconName = 'close',
|
|
52
|
+
debugName,
|
|
53
|
+
...props
|
|
54
|
+
} = modalProps
|
|
55
|
+
|
|
56
|
+
const variantStyles = useComponentStyle('Modal', {
|
|
57
|
+
variants: variants as any,
|
|
58
|
+
transform: StyleSheet.flatten,
|
|
59
|
+
styles
|
|
60
|
+
}) as ModalProps['styles']
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
function getStyles(key:MobileModalParts){
|
|
64
|
+
const s = [
|
|
65
|
+
variantStyles[key],
|
|
66
|
+
styles[key],
|
|
67
|
+
visible ? variantStyles[key + ':visible'] : {},
|
|
68
|
+
visible ? styles[key + ':visible'] : {},
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
return s
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const buttonStyles = React.useMemo(() => {
|
|
75
|
+
const buttonEntries = {}
|
|
76
|
+
|
|
77
|
+
for(const [key,style] of Object.entries(variantStyles)){
|
|
78
|
+
if(key.startsWith('closeButton')){
|
|
79
|
+
buttonEntries[capitalize(key.replace('closeButton', ''), true)] = style
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return buttonEntries
|
|
83
|
+
}, [variantStyles])
|
|
84
|
+
|
|
85
|
+
const boxAnimation = {
|
|
86
|
+
hidden : {
|
|
87
|
+
...variantStyles['box:pose'],
|
|
88
|
+
...styles['box:pose'],
|
|
89
|
+
},
|
|
90
|
+
visible : {
|
|
91
|
+
...variantStyles['box:pose:visible'],
|
|
92
|
+
...styles['box:pose:visible'],
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
|
|
98
|
+
<View style={getStyles('wrapper')} pointerEvents={visible ? 'auto' : 'none'} >
|
|
99
|
+
<AnimatedView style={getStyles('overlay')} transition={'opacity'}/>
|
|
100
|
+
<Scroll style={getStyles('innerWrapper')} contentContainerStyle={getStyles('innerWrapperScroll')}>
|
|
101
|
+
{
|
|
102
|
+
dismissOnBackdrop &&
|
|
103
|
+
<Touchable
|
|
104
|
+
debugName={`${debugName} modal backdrop`}
|
|
105
|
+
activeOpacity={1}
|
|
106
|
+
onPress={() => toggle()}
|
|
107
|
+
style={getStyles('touchableBackdrop')}
|
|
108
|
+
|
|
109
|
+
/>
|
|
110
|
+
}
|
|
111
|
+
<Animated component='View' config={boxAnimation} pose={visible ? 'visible' : 'hidden'} style={getStyles('box')}>
|
|
112
|
+
{
|
|
113
|
+
(title || showClose) &&
|
|
114
|
+
|
|
115
|
+
<View style={getStyles('header')}>
|
|
116
|
+
|
|
117
|
+
{typeof title === 'string' ? <Text text={title} style={getStyles('title')}/> : title}
|
|
118
|
+
|
|
119
|
+
{
|
|
120
|
+
(showClose && closable) &&
|
|
121
|
+
<Button debugName={`${debugName} modal close button`} icon={closeIconName as IconPlaceholder} variants={['icon']} onPress={toggle} styles={buttonStyles}/>
|
|
122
|
+
}
|
|
123
|
+
</View>
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
<View style={getStyles('body')}>
|
|
127
|
+
{children}
|
|
128
|
+
</View>
|
|
129
|
+
{
|
|
130
|
+
footer && <View style={getStyles('footer')}>
|
|
131
|
+
{footer}
|
|
132
|
+
</View>
|
|
133
|
+
}
|
|
134
|
+
</Animated>
|
|
135
|
+
|
|
136
|
+
</Scroll>
|
|
137
|
+
</View>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
export default Modal
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ButtonComposition, createDefaultVariantFactory, includePresets, ModalComposition, ModalStyles } from '@codeleap/common'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export const backgroundTransition = {
|
|
5
|
+
duration: 200,
|
|
6
|
+
ease: 'easeOut',
|
|
7
|
+
useNativeDriver: false,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const modalTransition = {
|
|
11
|
+
duration: 150,
|
|
12
|
+
ease: 'easeOut',
|
|
13
|
+
useNativeDriver: false,
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export type MobileModalParts =
|
|
18
|
+
| 'wrapper'
|
|
19
|
+
| 'overlay'
|
|
20
|
+
| 'innerWrapper'
|
|
21
|
+
| 'innerWrapperScroll'
|
|
22
|
+
| 'box'
|
|
23
|
+
| 'footer'
|
|
24
|
+
| 'body'
|
|
25
|
+
| 'header'
|
|
26
|
+
| 'touchableBackdrop'
|
|
27
|
+
| 'box:pose'
|
|
28
|
+
|
|
29
|
+
| 'title'
|
|
30
|
+
| `closeButton${Capitalize<ButtonComposition>}`
|
|
31
|
+
|
|
32
|
+
export type MobileModalComposition = MobileModalParts | `${MobileModalParts}:visible`
|
|
33
|
+
|
|
34
|
+
const createModalStyle = createDefaultVariantFactory<MobileModalComposition>()
|
|
35
|
+
|
|
36
|
+
const presets = includePresets((style ) => createModalStyle(() => ({wrapper: style})))
|
|
37
|
+
|
|
38
|
+
const defaultModalStyles = ModalStyles
|
|
39
|
+
|
|
40
|
+
export const MobileModalStyles = {
|
|
41
|
+
...presets,
|
|
42
|
+
...defaultModalStyles,
|
|
43
|
+
default: createModalStyle((Theme) => {
|
|
44
|
+
|
|
45
|
+
const fullSize = {
|
|
46
|
+
...Theme.presets.whole,
|
|
47
|
+
position: 'absolute',
|
|
48
|
+
width: Theme?.values?.width,
|
|
49
|
+
height: Theme?.values?.height,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
wrapper: {
|
|
54
|
+
zIndex:1,
|
|
55
|
+
|
|
56
|
+
...fullSize
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
overlay: {
|
|
60
|
+
opacity: 0,
|
|
61
|
+
zIndex: 2,
|
|
62
|
+
|
|
63
|
+
backgroundColor: Theme.colors.black,
|
|
64
|
+
...fullSize
|
|
65
|
+
},
|
|
66
|
+
"overlay:visible": {
|
|
67
|
+
opacity: 0.5
|
|
68
|
+
},
|
|
69
|
+
innerWrapper: {
|
|
70
|
+
|
|
71
|
+
zIndex: 3,
|
|
72
|
+
},
|
|
73
|
+
innerWrapperScroll: {
|
|
74
|
+
display: 'flex',
|
|
75
|
+
alignItems: 'center',
|
|
76
|
+
...Theme.presets.justifyCenter,
|
|
77
|
+
minHeight: Theme.values.height,
|
|
78
|
+
zIndex: 3
|
|
79
|
+
},
|
|
80
|
+
box: {
|
|
81
|
+
width: '80%',
|
|
82
|
+
backgroundColor: Theme.colors.white,
|
|
83
|
+
zIndex: 10,
|
|
84
|
+
borderRadius: Theme.borderRadius.medium,
|
|
85
|
+
...Theme.spacing.padding(1)
|
|
86
|
+
|
|
87
|
+
},
|
|
88
|
+
touchableBackdrop: {
|
|
89
|
+
...fullSize,
|
|
90
|
+
|
|
91
|
+
zIndex:5
|
|
92
|
+
},
|
|
93
|
+
"box:pose": {
|
|
94
|
+
opacity: 0,
|
|
95
|
+
scale: 0.8,
|
|
96
|
+
y: Theme.values.height * 0.15,
|
|
97
|
+
transition: modalTransition,
|
|
98
|
+
},
|
|
99
|
+
"box:pose:visible": {
|
|
100
|
+
y: 0,
|
|
101
|
+
opacity: 1,
|
|
102
|
+
scale: 1,
|
|
103
|
+
transition: modalTransition,
|
|
104
|
+
},
|
|
105
|
+
header: {
|
|
106
|
+
flexDirection: 'row',
|
|
107
|
+
...Theme.presets.justifySpaceBetween,
|
|
108
|
+
...Theme.presets.alignCenter
|
|
109
|
+
},
|
|
110
|
+
closeButtonWrapper: {
|
|
111
|
+
alignSelf: 'center',
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
}),
|
|
119
|
+
popup: createModalStyle((Theme) => ({
|
|
120
|
+
|
|
121
|
+
}))
|
|
122
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import * as Animatable from 'react-native-animatable'
|
|
3
|
+
import { ComponentVariants, IconPlaceholder, OverlayComposition, OverlayStyles, useComponentStyle } from "@codeleap/common"
|
|
4
|
+
import { ReactNode } from "react"
|
|
5
|
+
import { InputLabel } from "./TextInput"
|
|
6
|
+
import { Button } from './Button'
|
|
7
|
+
|
|
8
|
+
import { View } from "./View"
|
|
9
|
+
import { StylesOf } from "../types/utility"
|
|
10
|
+
import { StyleSheet, ViewProps } from "react-native"
|
|
11
|
+
import { AnimatedTouchable } from '.'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export type OverlayProps = ViewProps & {
|
|
15
|
+
title?: ReactNode
|
|
16
|
+
visible?: boolean
|
|
17
|
+
showClose?: boolean
|
|
18
|
+
variants?: ComponentVariants<typeof OverlayStyles>
|
|
19
|
+
styles?: StylesOf<OverlayComposition>
|
|
20
|
+
style?: any
|
|
21
|
+
onPress?:() => void
|
|
22
|
+
} & React.ComponentPropsWithoutRef<typeof AnimatedTouchable>
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export const Overlay:React.FC<OverlayProps> = (overlayProps) => {
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
showClose,
|
|
29
|
+
title,
|
|
30
|
+
children,
|
|
31
|
+
visible,
|
|
32
|
+
styles,
|
|
33
|
+
style,
|
|
34
|
+
variants,
|
|
35
|
+
...props
|
|
36
|
+
} = overlayProps
|
|
37
|
+
|
|
38
|
+
const variantStyles = useComponentStyle('Overlay', {
|
|
39
|
+
styles,
|
|
40
|
+
transform: StyleSheet.flatten,
|
|
41
|
+
variants: variants as any
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const touchableStyle = [
|
|
45
|
+
variantStyles.wrapper,
|
|
46
|
+
styles.wrapper,
|
|
47
|
+
visible && variantStyles['wrapper:visible'],
|
|
48
|
+
visible && styles['wrapper:visible']
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
return <AnimatedTouchable
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
transition={'opacity'}
|
|
55
|
+
style={touchableStyle}
|
|
56
|
+
{...props}
|
|
57
|
+
>
|
|
58
|
+
<View>
|
|
59
|
+
|
|
60
|
+
{ (title || showClose) && (
|
|
61
|
+
<View style={variantStyles.header}>
|
|
62
|
+
<InputLabel style={variantStyles.title} label={title}/>
|
|
63
|
+
{
|
|
64
|
+
showClose && <Button variants={['icon']} icon={'close' as IconPlaceholder} style={variantStyles.closeButton}/>
|
|
65
|
+
}
|
|
66
|
+
</View>
|
|
67
|
+
)}
|
|
68
|
+
|
|
69
|
+
</View>
|
|
70
|
+
</AnimatedTouchable>
|
|
71
|
+
|
|
72
|
+
}
|
|
@@ -15,8 +15,7 @@ import {
|
|
|
15
15
|
import { Button } from './Button';
|
|
16
16
|
import { StylesOf } from '../types/utility';
|
|
17
17
|
import { Icon } from './Icon';
|
|
18
|
-
import {NativeSyntheticEvent,
|
|
19
|
-
import { useLogStyles } from '../utils/styles';
|
|
18
|
+
import {NativeSyntheticEvent, TextInput as NativeTextInput, TextInputChangeEventData} from 'react-native'
|
|
20
19
|
|
|
21
20
|
type IconProp = {name: IconPlaceholder, action?:() => void}
|
|
22
21
|
|
|
@@ -66,7 +65,7 @@ import { useLogStyles } from '../utils/styles';
|
|
|
66
65
|
...props
|
|
67
66
|
} = rawprops
|
|
68
67
|
|
|
69
|
-
const [
|
|
68
|
+
const [_ig, setFocus] = useState(false)
|
|
70
69
|
const [editedState, setEdited] = useState(edited)
|
|
71
70
|
|
|
72
71
|
const input = useRef<any>(null)
|
|
@@ -75,7 +74,6 @@ import { useLogStyles } from '../utils/styles';
|
|
|
75
74
|
variants,
|
|
76
75
|
responsiveVariants,
|
|
77
76
|
styles,
|
|
78
|
-
transform: StyleSheet.flatten
|
|
79
77
|
})
|
|
80
78
|
const InputElement = NativeTextInput
|
|
81
79
|
|
|
@@ -109,22 +107,27 @@ import { useLogStyles } from '../utils/styles';
|
|
|
109
107
|
|
|
110
108
|
const {showError, error} = useValidate(value, validate)
|
|
111
109
|
|
|
112
|
-
|
|
110
|
+
|
|
111
|
+
const leftIconStyle = {
|
|
112
|
+
...variantStyles.icon,
|
|
113
|
+
...(showError ? variantStyles['icon:error'] : {} ),
|
|
114
|
+
...variantStyles.leftIcon,
|
|
115
|
+
...(showError ? variantStyles['leftIcon:error'] : {} ),
|
|
116
|
+
}
|
|
113
117
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return StyleSheet.flatten(requestedStyles)
|
|
118
|
+
const rightIconStyle = {
|
|
119
|
+
...variantStyles.icon,
|
|
120
|
+
...(showError ? variantStyles['icon:error'] : {} ),
|
|
121
|
+
...variantStyles.rightIcon,
|
|
122
|
+
...(showError ? variantStyles['rightIcon:error'] : {} ),
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getStyles(key:TextInputComposition){
|
|
126
|
+
const requestedStyles = [variantStyles[key], showError ? variantStyles[key + ':error'] : {}]
|
|
127
|
+
return requestedStyles
|
|
126
128
|
}
|
|
127
129
|
|
|
130
|
+
|
|
128
131
|
return (
|
|
129
132
|
<View
|
|
130
133
|
style={getStyles('wrapper')}
|
|
@@ -134,7 +137,7 @@ import { useLogStyles } from '../utils/styles';
|
|
|
134
137
|
<View style={getStyles('innerWrapper')}>
|
|
135
138
|
|
|
136
139
|
|
|
137
|
-
<InputIcon {...leftIcon} style={
|
|
140
|
+
<InputIcon {...leftIcon} style={leftIconStyle}/>
|
|
138
141
|
<InputElement
|
|
139
142
|
ref={input}
|
|
140
143
|
secureTextEntry={password && !textIsVisible}
|
|
@@ -150,13 +153,16 @@ import { useLogStyles } from '../utils/styles';
|
|
|
150
153
|
visibilityToggle ?
|
|
151
154
|
<InputIcon name={
|
|
152
155
|
(textIsVisible ? 'input-visiblity:visible' : 'input-visiblity:hidden') as IconPlaceholder
|
|
153
|
-
} action={() => setTextVisible()} style={
|
|
156
|
+
} action={() => setTextVisible()} style={rightIconStyle}/>
|
|
154
157
|
:
|
|
155
|
-
<InputIcon {...rightIcon} style={
|
|
158
|
+
<InputIcon {...rightIcon} style={rightIconStyle}/>
|
|
156
159
|
}
|
|
157
160
|
</View>
|
|
158
161
|
|
|
159
|
-
<FormError message={error.message} style={
|
|
162
|
+
<FormError message={error.message} style={{
|
|
163
|
+
...variantStyles.error,
|
|
164
|
+
|
|
165
|
+
}}/>
|
|
160
166
|
|
|
161
167
|
|
|
162
168
|
</View>
|
|
@@ -189,7 +195,7 @@ import { useLogStyles } from '../utils/styles';
|
|
|
189
195
|
|
|
190
196
|
switch (typeof label){
|
|
191
197
|
case 'string':
|
|
192
|
-
return <Text
|
|
198
|
+
return <Text style={style} text={label}/>
|
|
193
199
|
case 'object':
|
|
194
200
|
|
|
195
201
|
return label
|