react-native-varia 0.2.1 → 0.2.3

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.
@@ -1,202 +0,0 @@
1
- import React, {createContext, useContext, useState, ReactNode} from 'react'
2
- import {
3
- View,
4
- // Text,
5
- TouchableOpacity,
6
- ScrollView,
7
- TouchableWithoutFeedback,
8
- StyleSheet,
9
- } from 'react-native'
10
- import Text from './Text'
11
- import {StyleSheet as UniStyleSheet} from 'react-native-unistyles'
12
- import {SelectStyles, SelectDefaultVariants} from '../theme/Select.recipe'
13
- import {PalettesWithNestedKeys} from '../style/varia/types'
14
- import {UnistylesVariants} from 'react-native-unistyles'
15
- import {Portal} from '@gorhom/portal'
16
-
17
- type SelectVariants = UnistylesVariants<typeof SelectStyles>
18
-
19
- interface Option {
20
- label: string
21
- value: string
22
- }
23
-
24
- interface SelectContextType {
25
- value: string
26
- setValue: (val: string) => void
27
- isOpen: boolean
28
- setIsOpen: (open: boolean) => void
29
- options: Option[]
30
- colorPalette: PalettesWithNestedKeys
31
- variant: SelectVariants['variant']
32
- size: SelectVariants['size']
33
- }
34
-
35
- const SelectContext = createContext<SelectContextType | undefined>(undefined)
36
-
37
- const useSelect = () => {
38
- const context = useContext(SelectContext)
39
- if (!context)
40
- throw new Error('Select subcomponent must be used within Select.Root')
41
- return context
42
- }
43
-
44
- type RootProps = SelectVariants & {
45
- options: Option[]
46
- value?: string
47
- onChange?: (val: string) => void
48
- defaultValue?: string
49
- placeholder?: string
50
- colorPalette?: PalettesWithNestedKeys
51
- flex?: number
52
- children: ReactNode
53
- portalHostName?: string
54
- }
55
-
56
- export const Select = {
57
- Root: ({
58
- options,
59
- value: propValue,
60
- onChange: propOnChange,
61
- defaultValue = '',
62
- placeholder = 'Selecciona una opción',
63
- variant = SelectDefaultVariants.variant,
64
- size = SelectDefaultVariants.size,
65
- colorPalette = 'accent',
66
- flex = 1,
67
- children,
68
- portalHostName = 'select',
69
- }: RootProps) => {
70
- SelectStyles.useVariants({variant, size})
71
-
72
- const [internalValue, setInternalValue] = useState<string>(defaultValue)
73
- const [isOpen, setIsOpen] = useState(false)
74
- const isControlled = propValue !== undefined && propOnChange !== undefined
75
- const value = isControlled ? propValue! : internalValue
76
-
77
- const setValue = (val: string) => {
78
- if (isControlled) propOnChange!(val)
79
- else setInternalValue(val)
80
- setIsOpen(false)
81
- }
82
-
83
- return (
84
- <SelectContext.Provider
85
- value={{
86
- value,
87
- setValue,
88
- isOpen,
89
- setIsOpen,
90
- options,
91
- colorPalette,
92
- variant,
93
- size,
94
- }}>
95
- <View style={[styles.container(flex)]}>{children}</View>
96
-
97
- {isOpen && (
98
- <Portal hostName={portalHostName}>
99
- <View style={styles.modalOverlay}>
100
- <TouchableWithoutFeedback onPress={() => setIsOpen(false)}>
101
- <View style={styles.backdrop} />
102
- </TouchableWithoutFeedback>
103
- <View
104
- style={[
105
- styles.modalContent,
106
- SelectStyles.ModalContainer(colorPalette),
107
- ]}>
108
- <ScrollView
109
- contentContainerStyle={SelectStyles.itemsContainer(
110
- colorPalette,
111
- )}>
112
- {options.map(opt => (
113
- <TouchableOpacity
114
- key={opt.value}
115
- onPress={() => setValue(opt.value)}>
116
- <View
117
- style={[
118
- styles.item,
119
- SelectStyles.item(colorPalette, value === opt.value),
120
- ]}>
121
- <Text
122
- style={SelectStyles.itemText(
123
- colorPalette,
124
- value === opt.value,
125
- )}>
126
- {opt.label}
127
- </Text>
128
- </View>
129
- </TouchableOpacity>
130
- ))}
131
- </ScrollView>
132
- </View>
133
- </View>
134
- </Portal>
135
- )}
136
- </SelectContext.Provider>
137
- )
138
- },
139
-
140
- Trigger: ({placeholder = 'Selecciona una opción'}) => {
141
- const {
142
- variant,
143
- size,
144
- value,
145
- setIsOpen,
146
- options,
147
- colorPalette = 'accent',
148
- } = useSelect()
149
- SelectStyles.useVariants({variant, size})
150
- const selectedOption = options.find(opt => opt.value === value)
151
-
152
- return (
153
- <TouchableWithoutFeedback onPress={() => setIsOpen(true)}>
154
- <View style={[styles.input, SelectStyles.input(colorPalette)]}>
155
- <Text style={SelectStyles.valueText(colorPalette, !!selectedOption)}>
156
- {selectedOption ? selectedOption.label : placeholder}
157
- </Text>
158
- </View>
159
- </TouchableWithoutFeedback>
160
- )
161
- },
162
- }
163
-
164
- const styles = UniStyleSheet.create({
165
- container: (flex: number) => ({
166
- flexGrow: flex,
167
- flexDirection: 'row',
168
- justifyContent: 'center',
169
- }),
170
- input: {
171
- flex: 1,
172
- flexDirection: 'row',
173
- alignItems: 'center',
174
- justifyContent: 'center',
175
- },
176
- item: {
177
- paddingVertical: 2,
178
- paddingHorizontal: 8,
179
- alignItems: 'center',
180
- flexDirection: 'row',
181
- },
182
- modalOverlay: {
183
- position: 'absolute',
184
- top: 0,
185
- left: 0,
186
- right: 0,
187
- bottom: 0,
188
- justifyContent: 'center',
189
- alignItems: 'center',
190
- },
191
- backdrop: {
192
- ...StyleSheet.absoluteFillObject,
193
- backgroundColor: 'rgba(0,0,0,0.3)',
194
- },
195
- modalContent: {
196
- maxHeight: '50%',
197
- width: '80%',
198
- backgroundColor: 'white',
199
- borderRadius: 8,
200
- overflow: 'hidden',
201
- },
202
- })
@@ -1,153 +0,0 @@
1
- import React, {useState} from 'react'
2
- import {
3
- View,
4
- Text,
5
- TouchableOpacity,
6
- ScrollView,
7
- TouchableWithoutFeedback,
8
- } from 'react-native'
9
- import {StyleSheet} from 'react-native-unistyles'
10
- import {SelectStyles, SelectDefaultVariants} from '../theme/Select.recipe'
11
- import {PalettesWithNestedKeys} from '../style/varia/types'
12
- import {UnistylesVariants} from 'react-native-unistyles'
13
- import {Modal} from './Modal'
14
-
15
- type SelectVariants = UnistylesVariants<typeof SelectStyles>
16
-
17
- interface Option {
18
- label: string
19
- value: string
20
- }
21
-
22
- type SelectProps = SelectVariants & {
23
- options: Option[]
24
- value?: string
25
- onChange?: (value: string) => void
26
- onBlur?: () => void
27
- defaultValue?: string
28
- placeholder?: string
29
- colorPalette?: PalettesWithNestedKeys
30
- flex?: number
31
- }
32
-
33
- export const Select = ({
34
- options,
35
- value: propValue,
36
- onChange: propOnChange,
37
- onBlur: propOnBlur,
38
- defaultValue = '',
39
- placeholder = 'Selecciona una opción',
40
- variant = SelectDefaultVariants.variant,
41
- size = SelectDefaultVariants.size,
42
- colorPalette = 'accent',
43
- flex = 1,
44
- }: SelectProps) => {
45
- SelectStyles.useVariants({
46
- variant,
47
- size,
48
- })
49
-
50
- const [isOpen, setIsOpen] = useState(false)
51
- const [internalValue, setInternalValue] = useState<string>(defaultValue)
52
-
53
- const isControlled = propValue !== undefined && propOnChange !== undefined
54
-
55
- const value = isControlled ? propValue! : internalValue
56
-
57
- const handleSelect = (val: string) => {
58
- if (isControlled) {
59
- propOnChange!(val)
60
- } else {
61
- setInternalValue(val)
62
- }
63
- setIsOpen(false)
64
- }
65
-
66
- const selectedOption = options.find(opt => opt.value === value)
67
-
68
- return (
69
- <>
70
- <TouchableWithoutFeedback
71
- onPress={() => {
72
- setIsOpen(true)
73
- propOnBlur?.()
74
- }}>
75
- <View
76
- style={[
77
- styles.container(flex),
78
- SelectStyles.container(colorPalette),
79
- ]}>
80
- <View style={[styles.input, SelectStyles.input(colorPalette)]}>
81
- <Text
82
- style={[SelectStyles.valueText(colorPalette, !!selectedOption)]}>
83
- {selectedOption ? selectedOption.label : placeholder}
84
- </Text>
85
- </View>
86
- </View>
87
- </TouchableWithoutFeedback>
88
-
89
- {/* Modal con lista de opciones */}
90
- <Modal.Root
91
- isOpen={isOpen}
92
- setIsOpen={setIsOpen}
93
- colorPalette={colorPalette}
94
- variant="outline"
95
- portalHostName="select">
96
- <Modal.Overlay variant={'outline'} customStyle={SelectStyles}>
97
- <Modal.Content>
98
- <Modal.Body>
99
- <ScrollView
100
- style={[SelectStyles.ModalContainer(colorPalette)]}
101
- contentContainerStyle={[
102
- SelectStyles.itemsContainer(colorPalette),
103
- ]}>
104
- {options.map(item => (
105
- <TouchableOpacity
106
- key={item.value}
107
- onPress={() => handleSelect(item.value)}>
108
- <View
109
- style={[
110
- styles.item,
111
- SelectStyles.item(
112
- colorPalette,
113
- selectedOption?.value === item.value,
114
- ),
115
- ]}>
116
- <Text
117
- style={SelectStyles.itemText(
118
- colorPalette,
119
- selectedOption?.value === item.value,
120
- )}>
121
- {item.label}
122
- </Text>
123
- </View>
124
- </TouchableOpacity>
125
- ))}
126
- </ScrollView>
127
- </Modal.Body>
128
- </Modal.Content>
129
- </Modal.Overlay>
130
- </Modal.Root>
131
- </>
132
- )
133
- }
134
-
135
- const styles = StyleSheet.create({
136
- container: (flex: number) => ({
137
- flexGrow: flex,
138
- flexDirection: 'row',
139
- justifyContent: 'center',
140
- }),
141
- input: {
142
- flex: 1,
143
- flexDirection: 'row',
144
- alignItems: 'center',
145
- justifyContent: 'center',
146
- },
147
- item: {
148
- paddingVertical: 2,
149
- paddingHorizontal: 8,
150
- alignItems: 'center',
151
- flexDirection: 'row',
152
- },
153
- })
@@ -1,174 +0,0 @@
1
- import {TouchableWithoutFeedback} from 'react-native'
2
- import Animated, {
3
- Easing,
4
- useAnimatedStyle,
5
- useSharedValue,
6
- withSpring,
7
- withTiming,
8
- } from 'react-native-reanimated'
9
- import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
10
- import {useAnimatedVariantColor} from 'react-native-unistyles/reanimated'
11
- import {useLayoutEffect, useRef, useState} from 'react'
12
- import {SwitchTokens, SwitchStyles} from '../theme/Switch.recipe'
13
- import {PalettesWithNestedKeys} from '../style/varia/types'
14
-
15
- const animations = {
16
- withSpring,
17
- withTiming,
18
- }
19
-
20
- type AnimationType = 'withSpring' | 'withTiming'
21
-
22
- type SwitchVariants = UnistylesVariants<typeof SwitchStyles>
23
-
24
- type SwitchProps = SwitchVariants & {
25
- colorPalette?: PalettesWithNestedKeys
26
- value?: boolean
27
- animation?: keyof typeof SwitchTokens.variants.animation
28
- onValueChange?: (value: boolean) => void
29
- flex?: number
30
- }
31
-
32
- const Switch = ({
33
- colorPalette = 'accent',
34
- value,
35
- animation = SwitchTokens.defaultProps.animation,
36
- onValueChange = () => {},
37
- variant = SwitchTokens.defaultProps.variant,
38
- size = SwitchTokens.defaultProps.size,
39
- flex = 1,
40
- }: SwitchProps) => {
41
- const animatedRef = useRef(null)
42
-
43
- SwitchStyles.useVariants({
44
- variant,
45
- size,
46
- enabled: value,
47
- })
48
-
49
- const animationVariant =
50
- SwitchTokens.variants?.animation && animation
51
- ? SwitchTokens.variants.animation[animation]
52
- : {
53
- type: 'withSpring' as AnimationType,
54
- props: {
55
- damping: 15,
56
- stiffness: 100,
57
- mass: 1,
58
- },
59
- }
60
- console.log('🚀 ~ animationVariant:', animationVariant)
61
-
62
- const color = useAnimatedVariantColor(
63
- SwitchStyles.container(colorPalette),
64
- 'backgroundColor',
65
- )
66
- const thumbColor = useAnimatedVariantColor(
67
- SwitchStyles.thumb(colorPalette),
68
- 'backgroundColor',
69
- )
70
- const thumbEnabledPosition = useSharedValue(0)
71
- const animatedValue = useSharedValue(0)
72
- const containerWidth = useSharedValue(0)
73
-
74
- useLayoutEffect(() => {
75
- //@ts-ignore
76
- animatedRef.current?.measure((x, y, width) => {
77
- containerWidth.value = width
78
- //@ts-ignore
79
- const thumbWidth = SwitchStyles.thumb(colorPalette).width
80
- //@ts-ignore
81
- const padding = SwitchStyles.container(colorPalette).padding || 0
82
- const trackBorderWidth =
83
- //@ts-ignore
84
- SwitchStyles.container(colorPalette).borderWidth || 0
85
- thumbEnabledPosition.value =
86
- width - thumbWidth - trackBorderWidth * 2 - padding * 2
87
- })
88
- }, [])
89
-
90
- const animatedStyle = useAnimatedStyle(() => {
91
- return {
92
- backgroundColor: animations[animationVariant.type](
93
- color.value,
94
- animationVariant.props,
95
- ),
96
- // backgroundColor: withTiming(color.value, {
97
- // duration: 100,
98
- // easing: Easing.ease,
99
- // }),
100
- }
101
- })
102
- const thumbAnimatedStyle = useAnimatedStyle(() => {
103
- return {
104
- backgroundColor: animations[animationVariant.type](
105
- thumbColor.value,
106
- animationVariant.props,
107
- ),
108
- // backgroundColor: withTiming(thumbColor.value, {
109
- // duration: 100,
110
- // easing: Easing.ease,
111
- // }),
112
- }
113
- })
114
-
115
- const circleTranslationStyle = useAnimatedStyle(() => {
116
- return {
117
- transform: [
118
- {
119
- translateX: animatedValue.value,
120
- },
121
- ],
122
- }
123
- })
124
-
125
- return (
126
- <TouchableWithoutFeedback
127
- onPress={() => {
128
- onValueChange(!value)
129
- animatedValue.value = animations[animationVariant.type](
130
- animatedValue.value === 0 ? thumbEnabledPosition.value : 0,
131
- animationVariant.props,
132
- )
133
- // animatedValue.value = withTiming(
134
- // animatedValue.value === 0 ? thumbEnabledPosition.value : 0,
135
- // {duration: 100, easing: Easing.ease},
136
- // )
137
- }}>
138
- <Animated.View
139
- ref={animatedRef}
140
- style={[
141
- styles.container(flex),
142
- animatedStyle,
143
- SwitchStyles.container(colorPalette),
144
- ]}>
145
- <Animated.View
146
- style={[
147
- styles.thumb,
148
- SwitchStyles.thumb(colorPalette),
149
- thumbAnimatedStyle,
150
- circleTranslationStyle,
151
- ]}
152
- />
153
- </Animated.View>
154
- </TouchableWithoutFeedback>
155
- )
156
- }
157
-
158
- export default Switch
159
-
160
- const styles = StyleSheet.create((theme, rt) => ({
161
- container: (flex: number) => ({
162
- // flex,
163
- flexGrow: flex,
164
- flexShrink: 0,
165
- alignSelf: 'flex-start',
166
- flexDirection: 'row',
167
- alignItems: 'center',
168
- margin: 0,
169
- borderRadius: 20,
170
- }),
171
- thumb: {
172
- borderRadius: 9999,
173
- },
174
- }))
@@ -1,83 +0,0 @@
1
- import { StyleSheet, UnistylesVariants } from "react-native-unistyles"
2
- import ButtonRaw from "./Button-old"
3
- import ButtonStyles from "../theme/Button.recipe-old"
4
-
5
- // const ButtonStyles = StyleSheet.create(theme => ({
6
- // container: {
7
- // variants: {
8
- // colorPalette: {
9
- // primary: {
10
- // backgroundColor: 'tomato',
11
- // },
12
- // secondary: {
13
- // backgroundColor: theme.colors.foreground2,
14
- // }
15
- // },
16
- // size: {
17
- // sm: {
18
- // height: 32,
19
- // maxHeight: 32,
20
- // padding: 6,
21
- // },
22
- // md: {
23
- // maxHeight: 48,
24
- // height: 48,
25
- // padding: 8,
26
- // },
27
- // lg: {
28
- // maxHeight: 64,
29
- // height: 64,
30
- // padding: 12,
31
- // },
32
- // xl: {
33
- // maxHeight: 80,
34
- // height: 80,
35
- // padding: 16,
36
- // }
37
- // }
38
- // },
39
- // },
40
- // text: {
41
- // variants: {
42
- // colorPalette: {
43
- // primary: {
44
- // color: 'white',
45
- // },
46
- // secondary: {
47
- // color: theme.colors.categoryAquamarine,
48
- // }
49
- // },
50
- // size: {
51
- // sm: {
52
- // fontSize: 24,
53
- // },
54
- // md: {
55
- // fontSize: 28,
56
- // },
57
- // lg: {
58
- // fontSize: 32,
59
- // },
60
- // xl: {
61
- // fontSize: 36,
62
- // }
63
- // }
64
- // }
65
- // }
66
- // }))
67
-
68
- type ButtonVariants = UnistylesVariants<typeof ButtonStyles>;
69
-
70
- type ButtonProps = ButtonVariants & {
71
- onPress: () => void;
72
- };
73
-
74
- export const Button = ({ size, colorPalette, ...props }: ButtonProps) => {
75
- return (
76
- <ButtonRaw
77
- buttonStyles={ButtonStyles}
78
- size={size}
79
- colorPalette={colorPalette}
80
- {...props}
81
- />
82
- );
83
- };
@@ -1,74 +0,0 @@
1
- import {VStack, HStack} from '../patterns'
2
- import Text from './Text'
3
-
4
- const LayoutTest = () => {
5
- return (
6
- <VStack
7
- // flex={1}
8
- style={{
9
- flexGrow: 1,
10
- // flexShrink: 1,
11
- alignSelf: 'stretch',
12
- alignItems: 'stretch',
13
- backgroundColor: 'red',
14
- gap: 10,
15
- }}>
16
- <VStack
17
- style={{
18
- // flexGrow: 1,
19
- // flexShrink: 1,
20
- // alignSelf: 'stretch',
21
- backgroundColor: 'pink',
22
- }}>
23
- <Component />
24
- <Component />
25
- </VStack>
26
- <VStack
27
- style={{
28
- borderWidth: 5,
29
- borderColor: 'yellow',
30
- // flexGrow: 1,
31
- // flexShrink: 1,
32
- // alignSelf: 'stretch',
33
- backgroundColor: 'pink',
34
- }}>
35
- <Component />
36
- <Component />
37
- </VStack>
38
- </VStack>
39
- )
40
- }
41
-
42
- const Component = () => {
43
- return (
44
- <VStack
45
- style={{
46
- borderWidth: 1,
47
- borderColor: 'black',
48
- // flexGrow: 1,
49
- alignSelf: 'stretch',
50
- backgroundColor: 'blue',
51
- // flexShrink: 0,
52
- // alignSelf: 'flex-start',
53
- }}>
54
- <Text>hola</Text>
55
- <HStack
56
- style={{
57
- flexShrink: 0,
58
- flexGrow: 1,
59
- backgroundColor: 'green',
60
- minHeight: 50,
61
- maxHeight: 50,
62
- width: '100%',
63
- // opacity: 0.5,
64
- }}
65
- />
66
- <VStack>
67
- <Text>hola</Text>
68
- <Text>hola</Text>
69
- </VStack>
70
- </VStack>
71
- )
72
- }
73
-
74
- export default LayoutTest