react-native-varia 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +53 -0
  2. package/bin/cli.js +200 -0
  3. package/lib/components/Badge.tsx +96 -0
  4. package/lib/components/Button.tsx +131 -0
  5. package/lib/components/CircleProgress.tsx +180 -0
  6. package/lib/components/Divider.tsx +43 -0
  7. package/lib/components/GradientBackground.tsx +68 -0
  8. package/lib/components/GradientText.tsx +121 -0
  9. package/lib/components/Icon.tsx +13 -0
  10. package/lib/components/IconWrapper.tsx +109 -0
  11. package/lib/components/Input.tsx +120 -0
  12. package/lib/components/Link.tsx +87 -0
  13. package/lib/components/Modal.tsx +157 -0
  14. package/lib/components/ReText.tsx +124 -0
  15. package/lib/components/Slider.tsx +334 -0
  16. package/lib/components/Slideshow.tsx +317 -0
  17. package/lib/components/SlidingDrawer.tsx +307 -0
  18. package/lib/components/Spinner.tsx +44 -0
  19. package/lib/components/Switch.tsx +224 -0
  20. package/lib/components/Text.tsx +107 -0
  21. package/lib/components/index.tsx +83 -0
  22. package/lib/mixins.ts +180 -0
  23. package/lib/patterns/index.tsx +426 -0
  24. package/lib/theme/Badge.recipe.tsx +68 -0
  25. package/lib/theme/Button.recipe-old.tsx +67 -0
  26. package/lib/theme/Button.recipe.tsx +83 -0
  27. package/lib/theme/CircleProgress.recipe.tsx +42 -0
  28. package/lib/theme/GradientBackground.recipe.tsx +38 -0
  29. package/lib/theme/GradientText.recipe.tsx +49 -0
  30. package/lib/theme/Icon.recipe.tsx +122 -0
  31. package/lib/theme/IconWrapper.recipe.tsx +121 -0
  32. package/lib/theme/Input.recipe.tsx +110 -0
  33. package/lib/theme/Link.recipe.tsx +51 -0
  34. package/lib/theme/Modal.recipe.tsx +34 -0
  35. package/lib/theme/ReText.recipe.tsx +7 -0
  36. package/lib/theme/Slider.recipe.tsx +226 -0
  37. package/lib/theme/Slideshow.recipe.tsx +142 -0
  38. package/lib/theme/SlidingDrawer.recipe.tsx +91 -0
  39. package/lib/theme/Spinner.recipe.tsx +8 -0
  40. package/lib/theme/Switch.recipe.tsx +70 -0
  41. package/lib/theme/Text.recipe.tsx +10 -0
  42. package/lib/types.ts +70 -0
  43. package/lib/utils.ts +80 -0
  44. package/package.json +18 -0
@@ -0,0 +1,68 @@
1
+ import {View, StyleSheet, type ColorValue} from 'react-native'
2
+ import Svg, {Defs, LinearGradient, Stop, Rect} from 'react-native-svg'
3
+ import {withUnistyles} from 'react-native-unistyles'
4
+ import {gradientBackgroundTokens} from '../theme/GradientBackground.recipe'
5
+
6
+ interface GradientBackgroundProps {
7
+ colorPalette?: keyof typeof gradientBackgroundTokens.variants.colorPalette
8
+ direction?: keyof typeof gradientBackgroundTokens.variants.direction
9
+ // colors: Record<string, ColorValue>;
10
+ colors: Record<string, ColorValue>
11
+ }
12
+
13
+ const BaseGradientBackground = ({
14
+ colorPalette = gradientBackgroundTokens.defaultProps.colorPalette,
15
+ direction = gradientBackgroundTokens.defaultProps.direction,
16
+ colors,
17
+ }: GradientBackgroundProps) => {
18
+ const tokenColorKey =
19
+ gradientBackgroundTokens.variants.colorPalette[colorPalette]
20
+ const startColor =
21
+ tokenColorKey.startColor in colors
22
+ ? colors[tokenColorKey.startColor]
23
+ : tokenColorKey.startColor
24
+
25
+ const endColor =
26
+ tokenColorKey.endColor in colors
27
+ ? colors[tokenColorKey.endColor]
28
+ : tokenColorKey.endColor
29
+
30
+ const directionVariant =
31
+ gradientBackgroundTokens.variants.direction[direction]
32
+
33
+ return (
34
+ <View style={styles.container}>
35
+ <Svg
36
+ width="100%"
37
+ height="100%"
38
+ viewBox="0 0 100 100"
39
+ preserveAspectRatio="none">
40
+ <Defs>
41
+ <LinearGradient
42
+ id="grad"
43
+ x1={directionVariant?.x1}
44
+ y1={directionVariant?.y1}
45
+ x2={directionVariant?.x2}
46
+ y2={directionVariant?.y2}>
47
+ <Stop offset="0%" stopColor={startColor} stopOpacity="1" />
48
+ <Stop offset="100%" stopColor={endColor} stopOpacity="1" />
49
+ </LinearGradient>
50
+ </Defs>
51
+ <Rect width="100" height="100" fill="url(#grad)" />
52
+ </Svg>
53
+ </View>
54
+ )
55
+ }
56
+
57
+ const styles = StyleSheet.create({
58
+ container: {
59
+ ...StyleSheet.absoluteFillObject,
60
+ },
61
+ })
62
+
63
+ // export default GradientBackground;
64
+ const GradientBackground = withUnistyles(BaseGradientBackground, theme => ({
65
+ colors: theme.colors,
66
+ }))
67
+
68
+ export default GradientBackground
@@ -0,0 +1,121 @@
1
+ import {View, type ColorValue} from 'react-native'
2
+ import Svg, {
3
+ Defs,
4
+ LinearGradient,
5
+ Stop,
6
+ Text,
7
+ type NumberProp,
8
+ } from 'react-native-svg'
9
+ import {StyleSheet, withUnistyles} from 'react-native-unistyles'
10
+ import {gradientTextTokens} from '../theme/GradientText.recipe'
11
+ import {TextSemanticSizes} from '../style/types'
12
+
13
+ interface GradientTextProps {
14
+ colorPalette?: keyof typeof gradientTextTokens.variants.colorPalette
15
+ direction?: keyof typeof gradientTextTokens.variants.direction
16
+ // colors: Record<string, ColorValue>;
17
+ colors: Record<string, ColorValue>
18
+ as?: TextSemanticSizes
19
+ fontSize?: number | undefined
20
+ children?: React.ReactNode
21
+ }
22
+
23
+ const BaseGradientText = ({
24
+ as = 'body',
25
+ fontSize,
26
+ colorPalette = gradientTextTokens.defaultProps.colorPalette,
27
+ direction = gradientTextTokens.defaultProps.direction,
28
+ colors,
29
+ children,
30
+ }: GradientTextProps) => {
31
+ const tokenColorKey = gradientTextTokens.variants.colorPalette[colorPalette]
32
+ const startColor =
33
+ tokenColorKey.startColor in colors
34
+ ? colors[tokenColorKey.startColor]
35
+ : tokenColorKey.startColor
36
+
37
+ const endColor =
38
+ tokenColorKey.endColor in colors
39
+ ? colors[tokenColorKey.endColor]
40
+ : tokenColorKey.endColor
41
+
42
+ const directionVariant = gradientTextTokens.variants.direction[direction]
43
+
44
+ return (
45
+ <View style={{flexDirection: 'row'}}>
46
+ <View style={{width: '100%'}}>
47
+ <Svg height={styles[as](fontSize).fontSize + 20} width="100%">
48
+ <Defs>
49
+ <LinearGradient
50
+ id="gradient"
51
+ x1={directionVariant?.x1 as NumberProp}
52
+ y1={directionVariant?.y1 as NumberProp}
53
+ x2={directionVariant?.x2 as NumberProp}
54
+ y2={directionVariant?.y2 as NumberProp}>
55
+ <Stop offset="0%" stopColor={startColor as ColorValue} />
56
+ <Stop offset="100%" stopColor={endColor as ColorValue} />
57
+ </LinearGradient>
58
+ </Defs>
59
+ <Text
60
+ fill="url(#gradient)"
61
+ fontSize={styles[as](fontSize).fontSize}
62
+ fontWeight={400}
63
+ x="50%"
64
+ y={styles[as](fontSize).fontSize}
65
+ textAnchor="middle">
66
+ {children}
67
+ </Text>
68
+ </Svg>
69
+ </View>
70
+ </View>
71
+ )
72
+ }
73
+
74
+ const styles = StyleSheet.create(theme => ({
75
+ h1: fontSize => ({
76
+ //@ts-ignore
77
+ fontSize: fontSize || theme.fontSizes.xxl,
78
+ }),
79
+ h2: fontSize => ({
80
+ //@ts-ignore
81
+ fontSize: fontSize || theme.fontSizes.xl,
82
+ }),
83
+ h3: fontSize => ({
84
+ //@ts-ignore
85
+ fontSize: fontSize || theme.fontSizes.lg,
86
+ }),
87
+ h4: fontSize => ({
88
+ //@ts-ignore
89
+ fontSize: fontSize || theme.fontSizes.md,
90
+ }),
91
+ h5: fontSize => ({
92
+ //@ts-ignore
93
+ fontSize: fontSize || theme.fontSizes.sm,
94
+ }),
95
+ h6: fontSize => ({
96
+ //@ts-ignore
97
+ fontSize: fontSize || theme.fontSizes.xs,
98
+ }),
99
+ h7: fontSize => ({
100
+ //@ts-ignore
101
+ fontSize: fontSize || theme.fontSizes.xs,
102
+ }),
103
+ h8: fontSize => ({
104
+ //@ts-ignore
105
+ fontSize: fontSize || theme.fontSizes.xxs,
106
+ }),
107
+ h9: fontSize => ({
108
+ //@ts-ignore
109
+ fontSize: fontSize || theme.fontSizes.xxs,
110
+ }),
111
+ body: fontSize => ({
112
+ //@ts-ignore
113
+ fontSize: fontSize || theme.fontSizes.md,
114
+ }),
115
+ }))
116
+
117
+ const GradientText = withUnistyles(BaseGradientText, theme => ({
118
+ colors: theme.colors,
119
+ }))
120
+
121
+ export default GradientText
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import { IconWrapperProps, ThemedIcon } from '../components/IconWrapper';
3
+
4
+ const IconName = ({color, ...props}: Omit<IconWrapperProps, 'children' | 'colors'>) => {
5
+ return (
6
+ <ThemedIcon {...props} color={color}>
7
+ <>
8
+ {/* Icon content */}
9
+ </>
10
+ </ThemedIcon>
11
+ );
12
+ };
13
+ export default IconName;
@@ -0,0 +1,109 @@
1
+ import {
2
+ Children,
3
+ cloneElement,
4
+ Fragment,
5
+ isValidElement,
6
+ ReactElement,
7
+ type ReactNode,
8
+ } from 'react'
9
+ import Svg from 'react-native-svg'
10
+ import {View} from 'react-native'
11
+ import {withUnistyles} from 'react-native-unistyles'
12
+ import {IconTokens} from '../theme/IconWrapper.recipe'
13
+ import {ThemeColors} from '../style/types'
14
+
15
+ interface SVGChildProps {
16
+ color?: string
17
+ }
18
+ export type IconWrapperProps = {
19
+ size?: keyof typeof IconTokens.variants.size
20
+ colorPalette?: keyof typeof IconTokens.variants.colorPalette
21
+ children?: ReactElement<SVGChildProps>
22
+ scale?: number
23
+ color?: ThemeColors
24
+ rotation?: number
25
+ colors?: any
26
+ }
27
+
28
+ /**
29
+ * @param name string key icon name
30
+ * @param scale optional number scale icon size
31
+ * @param color optional ThemeColor color
32
+ * @param rotate optional number rotation of the icon
33
+ * @returns Icon react component
34
+ */
35
+ const Icon = ({
36
+ size = IconTokens.defaultProps.size,
37
+ colorPalette = IconTokens.defaultProps.colorPalette,
38
+ children,
39
+ scale = IconTokens.defaultProps.scale,
40
+ color,
41
+ rotation,
42
+ colors,
43
+ ...rest
44
+ }: IconWrapperProps) => {
45
+ const colorPaletteKey = IconTokens.variants.colorPalette[colorPalette]
46
+ const colorScheme =
47
+ colorPaletteKey.color in colors
48
+ ? colors[colorPaletteKey.color]
49
+ : colorPaletteKey.color
50
+ const resolvedColor = color
51
+ ? color in colors
52
+ ? colors[color]
53
+ : color
54
+ : colorScheme
55
+
56
+ const width = IconTokens.variants.size[size].width ?? 0
57
+ const height = IconTokens.variants.size[size].height ?? 0
58
+ const viewBoxWidth = IconTokens.variants.size[size].viewBoxWidth ?? 0
59
+ const viewBoxHeight = IconTokens.variants.size[size].viewBoxHeight ?? 0
60
+
61
+ return (
62
+ <View
63
+ style={{
64
+ width: scale * width,
65
+ height: scale * height,
66
+ transform: rotation ? [{rotate: `${rotation}deg`}] : [],
67
+ }}>
68
+ <Svg
69
+ width={scale * width}
70
+ height={scale * height}
71
+ viewBox={`0 0 ${viewBoxWidth} ${viewBoxHeight}`}
72
+ fill="none"
73
+ {...rest}>
74
+ {Children.map(children, child => {
75
+ if (isFragmentElement(child)) {
76
+ return cloneElement(
77
+ child,
78
+ {},
79
+ Children.map(child.props.children, pathChild => {
80
+ if (isValidElement(pathChild)) {
81
+ return cloneElement(
82
+ pathChild as React.ReactElement<{stroke?: string}>,
83
+ {
84
+ stroke: resolvedColor ?? colorScheme,
85
+ },
86
+ )
87
+ }
88
+ return pathChild
89
+ }),
90
+ )
91
+ }
92
+ return child
93
+ })}
94
+ </Svg>
95
+ </View>
96
+ )
97
+ }
98
+
99
+ export default Icon
100
+
101
+ export const ThemedIcon = withUnistyles(Icon, (theme, rt) => ({
102
+ colors: theme.colors,
103
+ }))
104
+
105
+ function isFragmentElement(
106
+ node: ReactNode,
107
+ ): node is React.ReactElement<{children?: ReactNode}> {
108
+ return isValidElement(node) && node.type === Fragment
109
+ }
@@ -0,0 +1,120 @@
1
+ import {
2
+ type InputModeOptions,
3
+ type KeyboardTypeOptions,
4
+ type StyleProp,
5
+ TextInput,
6
+ TextStyle,
7
+ View,
8
+ type ViewStyle,
9
+ } from 'react-native'
10
+ // import Text from './Text';
11
+ import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
12
+ // import Text from './Text';
13
+ import {InputTokens, InputStyles} from '../theme/Input.recipe'
14
+ import Text from './Text'
15
+
16
+ type InputVariants = UnistylesVariants<typeof InputStyles>
17
+
18
+ type InputProps = InputVariants & {
19
+ label?: string
20
+ onChange?: (value: string) => void
21
+ placeholder: string
22
+ inputMode?: InputModeOptions
23
+ keyboardType?: KeyboardTypeOptions
24
+ flex?: number
25
+ maxWidth?: number | string
26
+ password?: boolean
27
+ onFocus?: () => void
28
+ value: any
29
+ containerMixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
30
+ labelMixins?:
31
+ | StyleProp<ViewStyle>
32
+ | StyleProp<ViewStyle>[]
33
+ | StyleProp<TextStyle>
34
+ | StyleProp<TextStyle>[]
35
+ inputMixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
36
+ // containerStyle?: StyleProp<ViewStyle>;
37
+ // labelStyle?: StyleProp<ViewStyle>;
38
+ // inputStyle?: StyleProp<ViewStyle>;
39
+ }
40
+
41
+ const Input = ({
42
+ colorPalette = InputTokens.defaultProps.colorPalette,
43
+ size = InputTokens.defaultProps.size,
44
+ spacing = InputTokens.defaultProps.spacing,
45
+ label,
46
+ placeholder,
47
+ onChange,
48
+ inputMode,
49
+ keyboardType,
50
+ flex = 1,
51
+ maxWidth = '100%',
52
+ password = false,
53
+ onFocus = () => {},
54
+ value,
55
+ containerMixins,
56
+ labelMixins,
57
+ inputMixins,
58
+ }: // containerStyle,
59
+ // labelStyle,
60
+ // inputStyle,
61
+ InputProps) => {
62
+ InputStyles.useVariants({
63
+ colorPalette,
64
+ size,
65
+ spacing,
66
+ })
67
+
68
+ return (
69
+ <View
70
+ style={[
71
+ styles.container(flex, maxWidth),
72
+ // containerStyle && styles.customStyle(containerStyle),
73
+ containerMixins && containerMixins,
74
+ ]}>
75
+ {label && (
76
+ <Text
77
+ as="h5"
78
+ style={
79
+ [
80
+ // styles.label,
81
+ InputStyles.label,
82
+ // labelStyle && styles.customStyle(labelStyle),
83
+ labelMixins && labelMixins,
84
+ ] as any
85
+ }>
86
+ {label}
87
+ </Text>
88
+ )}
89
+ <TextInput
90
+ style={[
91
+ // styles.input,
92
+ InputStyles.input,
93
+ // inputStyle && styles.customStyle(inputStyle),
94
+ inputMixins && inputMixins,
95
+ ]}
96
+ value={value}
97
+ placeholder={placeholder}
98
+ inputMode={inputMode}
99
+ keyboardType={keyboardType}
100
+ secureTextEntry={password}
101
+ onFocus={onFocus}
102
+ onChangeText={onChange}
103
+ />
104
+ </View>
105
+ )
106
+ }
107
+
108
+ const styles = StyleSheet.create({
109
+ container: (flex, maxWidth) => ({
110
+ flex,
111
+ width: '100%',
112
+ maxWidth,
113
+ gap: 5,
114
+ }),
115
+ // customStyle: style => ({
116
+ // ...style,
117
+ // }),
118
+ })
119
+
120
+ export default Input
@@ -0,0 +1,87 @@
1
+ import {
2
+ Alert,
3
+ Linking,
4
+ TextStyle,
5
+ TouchableOpacity,
6
+ type StyleProp,
7
+ type ViewStyle,
8
+ } from 'react-native'
9
+ import Text from './Text'
10
+ import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
11
+ import LinkStyles from '../theme/Link.recipe'
12
+ import {TextSemanticSizes} from '../style/types'
13
+ type LinkVariants = UnistylesVariants<typeof LinkStyles>
14
+
15
+ type LinkProps = LinkVariants & {
16
+ text: string
17
+ url: string
18
+ underline?: boolean
19
+ as?: TextSemanticSizes
20
+ fontSize?: number
21
+ color?: string
22
+ style?: StyleProp<ViewStyle>
23
+ mixins?:
24
+ | StyleProp<ViewStyle>
25
+ | StyleProp<ViewStyle>[]
26
+ | StyleProp<TextStyle>
27
+ | StyleProp<TextStyle>[]
28
+ }
29
+
30
+ const Link = ({
31
+ colorPalette,
32
+ size,
33
+ text,
34
+ url,
35
+ underline,
36
+ as,
37
+ fontSize,
38
+ color,
39
+ mixins,
40
+ }: LinkProps) => {
41
+ LinkStyles.useVariants({
42
+ colorPalette,
43
+ size,
44
+ })
45
+
46
+ return (
47
+ <TouchableOpacity
48
+ onPress={async () => {
49
+ try {
50
+ await Linking.openURL(url)
51
+ } catch {
52
+ Alert.alert('No se pudo abrir este enlace')
53
+ }
54
+ }}>
55
+ <Text
56
+ as={as}
57
+ fontSize={fontSize}
58
+ // color={color}
59
+ style={
60
+ [
61
+ styles.link(
62
+ underline ? 'underline' : 'none',
63
+ // linkTokens.variants,
64
+ // linkTokens.customVariants
65
+ ),
66
+ LinkStyles.link,
67
+ // style && styles.customStyle(style),
68
+ color && {color},
69
+ mixins && mixins,
70
+ ] as any
71
+ }>
72
+ {text}
73
+ </Text>
74
+ </TouchableOpacity>
75
+ )
76
+ }
77
+
78
+ const styles = StyleSheet.create({
79
+ link: (underline): any => ({
80
+ textDecorationLine: underline,
81
+ }),
82
+ // customStyle: style => ({
83
+ // ...style,
84
+ // }),
85
+ })
86
+
87
+ export default Link
@@ -0,0 +1,157 @@
1
+ import {TouchableOpacity, TouchableWithoutFeedback, View} from 'react-native'
2
+ import Animated, {FadeIn, FadeOut, Keyframe} from 'react-native-reanimated'
3
+ import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
4
+ import Text from './Text'
5
+ import Svg, {Path} from 'react-native-svg'
6
+ import {ModalStyles, ModalTokens} from '../theme/Modal.recipe'
7
+
8
+ type ModalVariants = UnistylesVariants<typeof ModalStyles>
9
+
10
+ type ModalProps = ModalVariants & {
11
+ isOpen: boolean
12
+ setIsOpen: (isOpen: boolean) => void
13
+ children: React.ReactNode
14
+ heading?: string
15
+ }
16
+
17
+ // Define animations outside of the component to avoid re-creation on each render
18
+ const enteringModalContent = new Keyframe({
19
+ 0: {opacity: 0, transform: [{scale: 0.8}]},
20
+ 20: {opacity: 0.5, transform: [{scale: 0.9}]},
21
+ 100: {opacity: 1, transform: [{scale: 1}]},
22
+ }).duration(300)
23
+
24
+ const exitingModalContent = new Keyframe({
25
+ 0: {opacity: 1, transform: [{scale: 1}]},
26
+ 100: {opacity: 0, transform: [{scale: 0.8}]},
27
+ }).duration(200)
28
+
29
+ const Modal = ({
30
+ isOpen,
31
+ setIsOpen,
32
+ heading,
33
+ children,
34
+ colorPalette = ModalTokens.defaultProps.colorPalette,
35
+ }: ModalProps) => {
36
+ // const tokens = useTokens('modal')();
37
+ if (!isOpen) return null
38
+
39
+ // const resolvedColorScheme =
40
+ // colorScheme ??
41
+ // (tokens.defaultProps.colorScheme as keyof ModalColorSchemeVariants);
42
+
43
+ ModalStyles.useVariants({
44
+ colorPalette,
45
+ })
46
+
47
+ return (
48
+ <Animated.View
49
+ style={styles.overlay}
50
+ entering={FadeIn.duration(200)}
51
+ exiting={FadeOut.duration(250)}>
52
+ <TouchableWithoutFeedback onPress={() => setIsOpen(false)}>
53
+ <View style={StyleSheet.absoluteFillObject} />
54
+ </TouchableWithoutFeedback>
55
+ <Animated.View
56
+ // @ts-ignore
57
+ style={[styles.modalBox(), ModalStyles.container]}
58
+ entering={enteringModalContent}
59
+ exiting={exitingModalContent}>
60
+ <View style={styles.header(!heading)}>
61
+ <Text style={styles.headerTitle}>{!!heading && heading}</Text>
62
+ <View
63
+ style={{
64
+ position: 'absolute',
65
+ right: 0,
66
+ top: 0,
67
+ }}>
68
+ <CloseButton onClose={() => setIsOpen(false)} />
69
+ </View>
70
+ </View>
71
+ <View style={styles.content}>{children}</View>
72
+ </Animated.View>
73
+ </Animated.View>
74
+ )
75
+ }
76
+
77
+ // type ModalTokenType = ReturnType<Tokens['modal']>;
78
+ // type VariantsType = ModalTokenType['variants'];
79
+
80
+ const styles = StyleSheet.create(theme => {
81
+ return {
82
+ overlay: {
83
+ ...StyleSheet.absoluteFillObject,
84
+ backgroundColor: 'black',
85
+ zIndex: 1000,
86
+ justifyContent: 'center',
87
+ alignItems: 'center',
88
+ },
89
+ modalBox: () => ({
90
+ width: '80%',
91
+ justifyContent: 'center',
92
+ alignItems: 'center',
93
+ padding: 20,
94
+ borderRadius: 10,
95
+ // backgroundColor: theme.colors.background,
96
+ // boxShadow: '0px 0px 50px rgba(250, 250, 250, 0.6)',
97
+ // variants: {
98
+ // colorScheme: variants.colorScheme as any,
99
+ // },
100
+ }),
101
+ header: padding => ({
102
+ flexDirection: 'row',
103
+ justifyContent: 'space-between',
104
+ alignItems: 'center',
105
+ width: '100%',
106
+ marginBottom: 10,
107
+ padding: padding && 10,
108
+ }),
109
+ headerTitle: {
110
+ textAlign: 'center',
111
+ flex: 1,
112
+ },
113
+ closeButton: {
114
+ color: 'white',
115
+ },
116
+ content: {
117
+ width: '100%',
118
+ },
119
+ }
120
+ })
121
+
122
+ export default Modal
123
+
124
+ export interface CloseButtonProps {
125
+ scale?: number
126
+ color?: undefined
127
+ onClose: () => void
128
+ }
129
+
130
+ const defaultColor = 'white'
131
+
132
+ const CloseButton = ({
133
+ onClose,
134
+ scale = 1,
135
+ color,
136
+ ...rest
137
+ }: CloseButtonProps) => (
138
+ <TouchableOpacity onPress={onClose}>
139
+ <Svg
140
+ // TODO: fix types
141
+ //@ts-ignore
142
+ xmlns="http://www.w3.org/2000/svg"
143
+ width={scale * 24}
144
+ height={scale * 24}
145
+ viewBox={`0 0 ${24} ${24}`}
146
+ fill="none"
147
+ {...rest}>
148
+ <Path
149
+ stroke={color || defaultColor}
150
+ strokeLinecap="round"
151
+ strokeLinejoin="round"
152
+ strokeWidth={1.5}
153
+ d="m7.757 7.757 8.486 8.486M7.757 16.243l8.486-8.486"
154
+ />
155
+ </Svg>
156
+ </TouchableOpacity>
157
+ )