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,224 @@
1
+ import React, { useLayoutEffect, useRef } from 'react';
2
+ import Animated, {
3
+ useAnimatedStyle,
4
+ interpolateColor,
5
+ useSharedValue,
6
+ withTiming,
7
+ Easing,
8
+ } from 'react-native-reanimated';
9
+ import { runOnJS } from 'react-native-worklets';
10
+ import { ColorValue, TouchableWithoutFeedback } from 'react-native';
11
+ import { StyleSheet, UnistylesVariants, withUnistyles } from 'react-native-unistyles';
12
+ import { SwitchStyles, SwitchTokens } from '../theme/Switch.recipe';
13
+
14
+ type SwitchVariants = UnistylesVariants<typeof SwitchStyles>;
15
+
16
+ type SwitchProps = SwitchVariants & {
17
+ value: boolean;
18
+ onValueChange: (value: boolean) => void;
19
+ flex?: number;
20
+ thumbChildren?: React.ReactNode;
21
+ colors?: Record<string, ColorValue>;
22
+ };
23
+
24
+ // interface SwitchProps {
25
+ // value: boolean;
26
+ // onValueChange: (value: boolean) => void;
27
+ // size: keyof SwitchSizeVariants;
28
+ // colorScheme: keyof SwitchColorSchemeVariants;
29
+ // flex?: number;
30
+ // thumbChildren?: React.ReactNode;
31
+ // }
32
+
33
+ const Switch = ({
34
+ value,
35
+ onValueChange,
36
+ size,
37
+ colorPalette,
38
+ flex = 0,
39
+ thumbChildren: ThumbChildren,
40
+ colors
41
+ }: SwitchProps) => {
42
+ // const switchTokens = useTokens('switch')();
43
+ const animatedRef = useRef(null);
44
+
45
+ // const resolvedColorScheme =
46
+ // colorScheme ??
47
+ // (switchTokens.defaultProps.colorScheme as keyof SwitchColorSchemeVariants);
48
+ // const resolvedSize =
49
+ // size ?? (switchTokens.defaultProps.size as keyof SwitchSizeVariants);
50
+
51
+ SwitchStyles.useVariants({
52
+ // colorPalette: colorPalette,
53
+ size: size,
54
+ });
55
+
56
+ // const { styles, theme } = useStyles(stylesheet, {
57
+ // size,
58
+ // // type,
59
+ // });
60
+ const trackTokenColorKey = SwitchTokens.track.variants.colorPalette[colorPalette];
61
+ console.log("🚀 ~ trackTokenColorKey:", trackTokenColorKey)
62
+ const thumbTokenColorKey = SwitchTokens.thumb.variants.colorPalette[colorPalette];
63
+ console.log("🚀 ~ thumbTokenColorKey:", thumbTokenColorKey)
64
+ console.log("🚀 ~ colors:", colors)
65
+
66
+ const trackDisabledColor = colors[trackTokenColorKey?.disabled?.backgroundColor];
67
+ console.log("🚀 ~ trackDisabledColor:", trackDisabledColor)
68
+ const trackEnabledColor =
69
+ colors[trackTokenColorKey?.enabled?.backgroundColor];
70
+ console.log("🚀 ~ trackEnabledColor:", trackEnabledColor)
71
+ const thumbDisabledColor =
72
+ colors[thumbTokenColorKey?.disabled?.backgroundColor];
73
+ console.log("🚀 ~ thumbDisabledColor:", thumbDisabledColor)
74
+ const thumbEnabledColor =
75
+ colors[thumbTokenColorKey?.enabled?.backgroundColor];
76
+ console.log("🚀 ~ thumbEnabledColor:", thumbEnabledColor)
77
+ const trackBorderWidth = 1;
78
+ const trackBorderColor = 'white';
79
+ // const trackBorderWidth =
80
+ // switchTokens?.track?.variants?.colorScheme?.[colorScheme]?.borderWidth ?? 0;
81
+ // const trackBorderColor =
82
+ // switchTokens?.track?.variants?.colorScheme?.[colorScheme]?.borderColor ?? 'transparent';
83
+ const maxHeight = SwitchTokens?.track?.variants?.size?.[size]?.height;
84
+
85
+ const animatedValue = useSharedValue(0);
86
+ const containerWidth = useSharedValue(0);
87
+
88
+ useLayoutEffect(() => {
89
+ //@ts-ignore
90
+ animatedRef.current?.measure((x, y, width, height, pageX, pageY) => {
91
+ console.log("🚀 ~ animatedRef.current?.measure ~ width:", width)
92
+ const thumbWidth =
93
+ SwitchTokens?.thumb?.variants?.size?.[size]?.width ?? 0;
94
+ containerWidth.value = width - thumbWidth;
95
+ });
96
+ }, []);
97
+
98
+ const animate = () => {
99
+ if (animatedValue.value === 0) {
100
+ animatedValue.value = withTiming(
101
+ containerWidth.value - 6 - trackBorderWidth * 2,
102
+ {
103
+ duration: 200,
104
+ easing: Easing.ease,
105
+ },
106
+ () => {
107
+ runOnJS(onValueChange)(!value);
108
+ }
109
+ );
110
+ } else {
111
+ animatedValue.value = withTiming(
112
+ 0,
113
+ { duration: 200, easing: Easing.ease },
114
+ () => {
115
+ runOnJS(onValueChange)(!value);
116
+ }
117
+ );
118
+ }
119
+ };
120
+
121
+ const backgroundColorStyle = useAnimatedStyle(() => {
122
+ //@ts-ignore
123
+ const backgroundColor = interpolateColor(
124
+ animatedValue.value,
125
+ [0, containerWidth.value],
126
+ [trackDisabledColor, trackEnabledColor]
127
+ );
128
+ return { backgroundColor };
129
+ });
130
+ const circleTranslationStyle = useAnimatedStyle(() => {
131
+ //@ts-ignore
132
+ const backgroundColor = interpolateColor(
133
+ animatedValue.value,
134
+ [0, containerWidth.value],
135
+ [thumbDisabledColor, thumbEnabledColor]
136
+ );
137
+ return {
138
+ backgroundColor,
139
+ transform: [
140
+ {
141
+ translateX: animatedValue.value,
142
+ },
143
+ ],
144
+ };
145
+ });
146
+ return (
147
+ <TouchableWithoutFeedback
148
+ onPress={() => {
149
+ animate();
150
+ }}
151
+ >
152
+ <Animated.View
153
+ ref={animatedRef}
154
+ style={[
155
+ styles.container(
156
+ flex,
157
+ maxHeight,
158
+ trackBorderWidth,
159
+ trackBorderColor,
160
+ // switchTokens.track.variants
161
+ ),
162
+ SwitchStyles.track,
163
+ backgroundColorStyle,
164
+ ]}
165
+ testID="switch"
166
+ >
167
+ <Animated.View
168
+ style={[
169
+ styles.thumb(),
170
+ SwitchStyles.thumb,
171
+ circleTranslationStyle,
172
+ ]}
173
+ >
174
+ {ThumbChildren || null}
175
+ </Animated.View>
176
+ </Animated.View>
177
+ </TouchableWithoutFeedback>
178
+ );
179
+ };
180
+
181
+ // type SwitchTokenType = ReturnType<Tokens['switch']>; // This is the return of the function
182
+ // type TrackVariantsType = SwitchTokenType['track']['variants'];
183
+ // type ThumbVariantsType = SwitchTokenType['thumb']['variants'];
184
+
185
+ const styles = StyleSheet.create({
186
+ container: (
187
+ flex,
188
+ maxHeight,
189
+ borderWidth,
190
+ borderColor,
191
+ // variants: TrackVariantsType
192
+ ) => ({
193
+ // width: 60,
194
+ // height: 34,
195
+ flex,
196
+ maxHeight,
197
+ borderRadius: 9999,
198
+ justifyContent: 'center',
199
+ padding: 3,
200
+ borderWidth,
201
+ borderColor,
202
+ // variants: {
203
+ // size: variants.size,
204
+ // },
205
+ }),
206
+ thumb: (
207
+ // variants: ThumbVariantsType
208
+ ) => ({
209
+ borderRadius: 50,
210
+ justifyContent: 'center',
211
+ alignItems: 'center',
212
+ // variants: {
213
+ // size: variants.size,
214
+ // type: thumbVariants.type(theme),
215
+ // type: switchTokens.thumb.variants.type(theme),
216
+ // },
217
+ }),
218
+ });
219
+
220
+ export default Switch;
221
+
222
+ export const ThemedSwitch = withUnistyles(Switch, (theme, rt) => ({
223
+ colors: theme.colors,
224
+ }));
@@ -0,0 +1,107 @@
1
+ import {Text as RNText} from 'react-native'
2
+ import type {StyleProp, TextStyle} from 'react-native'
3
+ import {StyleSheet} from 'react-native-unistyles'
4
+ import textStyles from '../theme/Text.recipe'
5
+ // import { useTokens } from '../style/useTokens';
6
+
7
+ export interface Props {
8
+ as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'h7' | 'h8' | 'h9' | 'body'
9
+ fontSize?: number | undefined
10
+ color?: string | undefined
11
+ style?: TextStyle
12
+ children?: React.ReactNode
13
+ numberOfLines?: number
14
+ adjustsFontSizeToFit?: boolean
15
+ mixins?: StyleProp<TextStyle> | StyleProp<TextStyle>[]
16
+ }
17
+
18
+ const fontSizeDefined = (textStyles.text as any).fontSize // solo si realmente confías
19
+ const variant = fontSizeDefined ? undefined : 'h1'
20
+
21
+ const Text: React.FC<Props> = ({
22
+ as = variant,
23
+ fontSize,
24
+ color,
25
+ style,
26
+ children,
27
+ numberOfLines,
28
+ adjustsFontSizeToFit = false,
29
+ // mixins,
30
+ }) => {
31
+ // const textTokens = useTokens('text')();
32
+
33
+ styles.useVariants({
34
+ as,
35
+ })
36
+
37
+ return (
38
+ <RNText
39
+ style={[
40
+ textStyles.text,
41
+ styles.text(color, fontSize),
42
+ style,
43
+ // mixins && mixins,
44
+ ]}
45
+ numberOfLines={numberOfLines !== undefined ? numberOfLines : undefined}
46
+ adjustsFontSizeToFit={adjustsFontSizeToFit}>
47
+ {children}
48
+ </RNText>
49
+ )
50
+ }
51
+
52
+ const styles = StyleSheet.create(theme => ({
53
+ text: (color?: string, fontSize?: number) => {
54
+ return {
55
+ verticalAlign: 'bottom',
56
+ textAlign: 'left',
57
+ ...(color && {color: color}),
58
+ ...(fontSize && {fontSize: fontSize}),
59
+ variants: {
60
+ as: {
61
+ h1: {
62
+ //@ts-ignore
63
+ fontSize: fontSize || theme.fontSizes.xxl,
64
+ },
65
+ h2: {
66
+ //@ts-ignore
67
+ fontSize: fontSize || theme.fontSizes.xl,
68
+ },
69
+ h3: {
70
+ //@ts-ignore
71
+ fontSize: fontSize || theme.fontSizes.lg,
72
+ },
73
+ h4: {
74
+ //@ts-ignore
75
+ fontSize: fontSize || theme.fontSizes.md,
76
+ },
77
+ h5: {
78
+ //@ts-ignore
79
+ fontSize: fontSize || theme.fontSizes.sm,
80
+ },
81
+ h6: {
82
+ //@ts-ignore
83
+ fontSize: fontSize || theme.fontSizes.xs,
84
+ },
85
+ h7: {
86
+ //@ts-ignore
87
+ fontSize: fontSize || theme.fontSizes.xs,
88
+ },
89
+ h8: {
90
+ //@ts-ignore
91
+ fontSize: fontSize || theme.fontSizes.xxs,
92
+ },
93
+ h9: {
94
+ //@ts-ignore
95
+ fontSize: fontSize || theme.fontSizes.xxs,
96
+ },
97
+ body: {
98
+ //@ts-ignore
99
+ fontSize: fontSize || theme.fontSizes.md,
100
+ },
101
+ },
102
+ },
103
+ }
104
+ },
105
+ }))
106
+
107
+ export default Text
@@ -0,0 +1,83 @@
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
+ };
package/lib/mixins.ts ADDED
@@ -0,0 +1,180 @@
1
+ import {StyleSheet} from 'react-native-unistyles';
2
+ import { ThemeColors } from '../src/style/types';
3
+ import { extractThemeColor } from './utils';
4
+
5
+ // const extractThemeColor = (color: ThemeColors, theme: any) => {
6
+ // return color in theme.colors ? theme.colors[color] : color;
7
+ // }
8
+
9
+ const mixins = StyleSheet.create((theme, rt) => ({
10
+ size: (width: number, height: number = width) => ({
11
+ width,
12
+ height,
13
+ }),
14
+ row: {
15
+ justifyContent: 'center',
16
+ flexDirection: 'row',
17
+ },
18
+ gap: (gap: number) => ({
19
+ gap,
20
+ }),
21
+ center: {
22
+ alignItems: 'center',
23
+ justifyContent: 'center',
24
+ },
25
+ sx: (sx: any) => ({
26
+ ...sx,
27
+ }),
28
+ w: (width: number) => ({
29
+ width,
30
+ }),
31
+ h: (height: number) => ({
32
+ height,
33
+ }),
34
+ bg: (backgroundColor: ThemeColors) => ({
35
+ backgroundColor: extractThemeColor(backgroundColor, theme),
36
+ }),
37
+ flexColumn: (flex: number = 1) => ({
38
+ flex,
39
+ width: '100%',
40
+ }),
41
+ flexRow: (flex: number = 1) => ({
42
+ flex,
43
+ height: '100%',
44
+ }),
45
+ minMaxW: (minWidth: number, maxWidth: number) => ({
46
+ minWidth,
47
+ maxWidth,
48
+ }),
49
+ minMaxH: (minHeight: number, maxHeight: number) => ({
50
+ minHeight,
51
+ maxHeight,
52
+ }),
53
+ vw: (amount: number) => ({
54
+ width:
55
+ ((rt.screen.width - rt.insets.left - rt.insets.right) * amount) / 100,
56
+ }),
57
+ vh: (amount: number) => ({
58
+ height:
59
+ ((rt.screen.height - rt.insets.top - rt.insets.bottom) * amount) / 100,
60
+ }),
61
+ vwh: (amount: number) => ({
62
+ width:
63
+ ((rt.screen.width - rt.insets.left - rt.insets.right) * amount) / 100,
64
+ height:
65
+ ((rt.screen.height - rt.insets.top - rt.insets.bottom) * amount) / 100,
66
+ }),
67
+ self: (
68
+ alignSelf: 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch',
69
+ ) => ({
70
+ alignSelf,
71
+ }),
72
+ justify: (
73
+ justifyContent:
74
+ | 'flex-start'
75
+ | 'flex-end'
76
+ | 'center'
77
+ | 'space-around'
78
+ | 'space-between'
79
+ | 'space-evenly',
80
+ ) => ({
81
+ justifyContent,
82
+ }),
83
+ rtl: {
84
+ direction: 'rtl',
85
+ },
86
+ ar: (aspectRatio: number) => ({
87
+ aspectRatio,
88
+ }),
89
+ br: (borderRadius: number) => ({
90
+ borderRadius,
91
+ }),
92
+ bw: (borderWidth: number) => ({
93
+ borderWidth,
94
+ }),
95
+ bc: (borderColor: ThemeColors) => ({
96
+ borderColor: extractThemeColor(borderColor, theme),
97
+ }),
98
+ border: (borderWidth: number, borderColor: ThemeColors) => ({
99
+ borderWidth,
100
+ borderColor: extractThemeColor(borderColor, theme),
101
+ }),
102
+ m: (margin: number) => ({
103
+ margin,
104
+ }),
105
+ mt: (marginTop: number) => ({
106
+ marginTop,
107
+ }),
108
+ mb: (marginBottom: number) => ({
109
+ marginBottom,
110
+ }),
111
+ ml: (marginLeft: number) => ({
112
+ marginLeft,
113
+ }),
114
+ mr: (marginRight: number) => ({
115
+ marginRight,
116
+ }),
117
+ mx: (marginHorizontal: number) => ({
118
+ marginHorizontal,
119
+ }),
120
+ my: (marginVertical: number) => ({
121
+ marginVertical,
122
+ }),
123
+ p: (padding: number) => ({
124
+ padding,
125
+ }),
126
+ pt: (paddingTop: number) => ({
127
+ paddingTop,
128
+ }),
129
+ pb: (paddingBottom: number) => ({
130
+ paddingBottom,
131
+ }),
132
+ pl: (paddingLeft: number) => ({
133
+ paddingLeft,
134
+ }),
135
+ pr: (paddingRight: number) => ({
136
+ paddingRight,
137
+ }),
138
+ px: (paddingHorizontal: number) => ({
139
+ paddingHorizontal,
140
+ }),
141
+ py: (paddingVertical: number) => ({
142
+ paddingVertical,
143
+ }),
144
+ t: (top: number = 0) => ({
145
+ position: 'absolute',
146
+ top,
147
+ }),
148
+ b: (bottom: number = 0) => ({
149
+ position: 'absolute',
150
+ bottom,
151
+ }),
152
+ l: (left: number = 0) => ({
153
+ position: 'absolute',
154
+ left,
155
+ }),
156
+ r: (right: number = 0) => ({
157
+ position: 'absolute',
158
+ right,
159
+ }),
160
+ static: {
161
+ position: 'static',
162
+ },
163
+ absolute: {
164
+ position: 'absolute',
165
+ },
166
+ relative: {
167
+ position: 'relative',
168
+ },
169
+ z: (zIndex: number) => ({
170
+ zIndex,
171
+ }),
172
+ opacity: (opacity: number) => ({
173
+ opacity,
174
+ }),
175
+ circle: {
176
+ borderRadius: 9999,
177
+ },
178
+ }));
179
+
180
+ export default mixins;