react-native-varia 0.0.1 → 0.2.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/bin/cli.js +35 -18
- package/lib/components/Badge.tsx +31 -32
- package/lib/components/Button.tsx +20 -20
- package/lib/components/Checkbox.tsx +95 -0
- package/lib/components/CircleProgress.tsx +56 -66
- package/lib/components/Field.tsx +137 -0
- package/lib/components/GradientBackground.tsx +17 -18
- package/lib/components/GradientText.tsx +25 -64
- package/lib/components/IconWrapper.tsx +32 -25
- package/lib/components/Input.tsx +66 -68
- package/lib/components/Link.tsx +14 -28
- package/lib/components/Modal.tsx +197 -97
- package/lib/components/NewSelect.tsx +202 -0
- package/lib/components/NumberInput.tsx +226 -0
- package/lib/components/RadioGroup.tsx +195 -0
- package/lib/components/ReText.tsx +53 -87
- package/lib/components/Select.tsx +272 -0
- package/lib/components/SelectOld.tsx +153 -0
- package/lib/components/Slider.tsx +32 -40
- package/lib/components/Slideshow.tsx +174 -261
- package/lib/components/SlidingDrawer.tsx +216 -265
- package/lib/components/Spinner.tsx +21 -12
- package/lib/components/Switch.tsx +133 -180
- package/lib/components/Switchold.tsx +174 -0
- package/lib/components/Text.tsx +36 -83
- package/lib/components/layoutTest.tsx +74 -0
- package/lib/patterns/index.tsx +143 -202
- package/lib/theme/Badge.recipe.tsx +44 -39
- package/lib/theme/Button.recipe.tsx +139 -48
- package/lib/theme/Checkbox.recipe.tsx +121 -0
- package/lib/theme/CircleProgress.recipe.tsx +16 -22
- package/lib/theme/Field.recipe.tsx +66 -0
- package/lib/theme/GradientBackground.recipe.tsx +7 -20
- package/lib/theme/GradientText.recipe.tsx +42 -28
- package/lib/theme/IconWrapper.recipe.tsx +10 -85
- package/lib/theme/Input.recipe.tsx +76 -83
- package/lib/theme/Link.recipe.tsx +16 -43
- package/lib/theme/Modal.recipe.tsx +59 -21
- package/lib/theme/NumberInput.recipe.tsx +191 -0
- package/lib/theme/RadioGroup.recipe.tsx +163 -0
- package/lib/theme/ReText.recipe.tsx +4 -7
- package/lib/theme/Select.recipe.tsx +121 -0
- package/lib/theme/Slider.recipe.tsx +97 -181
- package/lib/theme/Slideshow.recipe.tsx +24 -102
- package/lib/theme/SlidingDrawer.recipe.tsx +21 -59
- package/lib/theme/Spinner.recipe.tsx +28 -3
- package/lib/theme/Switch.recipe.tsx +75 -54
- package/lib/theme/Text.recipe.tsx +66 -8
- package/lib/theme/animations.tsx +13 -0
- package/lib/varia/colorPalettes/amber.ts +54 -0
- package/lib/varia/colorPalettes/blue.ts +54 -0
- package/lib/varia/colorPalettes/bronze.ts +54 -0
- package/lib/varia/colorPalettes/brown.ts +54 -0
- package/lib/varia/colorPalettes/crimson.ts +55 -0
- package/lib/varia/colorPalettes/cyan.ts +54 -0
- package/lib/varia/colorPalettes/gold.ts +54 -0
- package/lib/varia/colorPalettes/grass.ts +54 -0
- package/lib/varia/colorPalettes/green.ts +54 -0
- package/lib/varia/colorPalettes/indigo.ts +54 -0
- package/lib/varia/colorPalettes/iris.ts +54 -0
- package/lib/varia/colorPalettes/jade.ts +54 -0
- package/lib/varia/colorPalettes/lime.ts +55 -0
- package/lib/varia/colorPalettes/mauve.ts +54 -0
- package/lib/varia/colorPalettes/mint.ts +54 -0
- package/lib/varia/colorPalettes/neutral.ts +54 -0
- package/lib/varia/colorPalettes/olive.ts +54 -0
- package/lib/varia/colorPalettes/orange.ts +54 -0
- package/lib/varia/colorPalettes/pink.ts +54 -0
- package/lib/varia/colorPalettes/plum.ts +54 -0
- package/lib/varia/colorPalettes/purple.ts +56 -0
- package/lib/varia/colorPalettes/red.ts +55 -0
- package/lib/varia/colorPalettes/ruby.ts +56 -0
- package/lib/varia/colorPalettes/sage.ts +56 -0
- package/lib/varia/colorPalettes/sand.ts +56 -0
- package/lib/varia/colorPalettes/sky.ts +56 -0
- package/lib/varia/colorPalettes/slate.ts +56 -0
- package/lib/varia/colorPalettes/teal.ts +56 -0
- package/lib/varia/colorPalettes/tomato.ts +56 -0
- package/lib/varia/colorPalettes/violet.ts +56 -0
- package/lib/varia/colorPalettes/yellow.ts +56 -0
- package/lib/varia/defaultTheme.ts +174 -0
- package/lib/varia/mixins.ts +223 -0
- package/lib/varia/textStyles.ts +48 -0
- package/lib/varia/types.ts +277 -0
- package/lib/varia/utils.ts +283 -0
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { program } = require("commander");
|
|
4
4
|
const path = require("path");
|
|
@@ -53,27 +53,44 @@ program
|
|
|
53
53
|
.description("CLI para instalar componentes de react-native-varia")
|
|
54
54
|
.version("1.0.0");
|
|
55
55
|
|
|
56
|
+
// program
|
|
57
|
+
// .command('setup')
|
|
58
|
+
// .description('Copia mixins y utils a src/styles')
|
|
59
|
+
// .action(() => {
|
|
60
|
+
// const sourceDir = path.join(__dirname, '../lib');
|
|
61
|
+
// const destDir = path.join(process.cwd(), 'src/style');
|
|
62
|
+
|
|
63
|
+
// const filesToCopy = ['mixins', 'utils', 'types'];
|
|
64
|
+
|
|
65
|
+
// filesToCopy.forEach((file) => {
|
|
66
|
+
// const srcPath = path.join(sourceDir, `${file}.ts`);
|
|
67
|
+
// const destPath = path.join(destDir, `${file}.ts`);
|
|
68
|
+
|
|
69
|
+
// try {
|
|
70
|
+
// fs.ensureDirSync(destDir); // Asegura que el directorio de destino exista
|
|
71
|
+
// fs.copySync(srcPath, destPath, { overwrite: true });
|
|
72
|
+
// console.log(`✅ ${file}.tsx copiado a ${destPath}`);
|
|
73
|
+
// } catch (err) {
|
|
74
|
+
// console.error(`❌ Error al copiar ${file}.tsx: ${err.message}`);
|
|
75
|
+
// }
|
|
76
|
+
// });
|
|
77
|
+
// });
|
|
78
|
+
|
|
56
79
|
program
|
|
57
80
|
.command('setup')
|
|
58
|
-
.description('Copia
|
|
81
|
+
.description('Copia la carpeta varia a src/styles/varia')
|
|
59
82
|
.action(() => {
|
|
60
|
-
const sourceDir = path.join(__dirname, '../lib');
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
const filesToCopy = ['mixins', 'utils', 'types'];
|
|
64
|
-
|
|
65
|
-
filesToCopy.forEach((file) => {
|
|
66
|
-
const srcPath = path.join(sourceDir, `${file}.ts`);
|
|
67
|
-
const destPath = path.join(destDir, `${file}.ts`);
|
|
83
|
+
const sourceDir = path.join(__dirname, '../lib/varia'); // carpeta a copiar
|
|
84
|
+
const destParentDir = path.join(process.cwd(), 'src/style'); // carpeta donde irá "varia"
|
|
85
|
+
const destDir = path.join(destParentDir, 'varia'); // ruta final completa
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
});
|
|
87
|
+
try {
|
|
88
|
+
fs.ensureDirSync(destParentDir); // asegúrate de que exista src/style
|
|
89
|
+
fs.copySync(sourceDir, destDir, { overwrite: true });
|
|
90
|
+
console.log(`✅ Carpeta "varia" copiada a ${destDir}`);
|
|
91
|
+
} catch (err) {
|
|
92
|
+
console.error(`❌ Error al copiar la carpeta "varia": ${err.message}`);
|
|
93
|
+
}
|
|
77
94
|
});
|
|
78
95
|
|
|
79
96
|
program
|
package/lib/components/Badge.tsx
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import {Text, View, ViewStyle, StyleProp} from 'react-native'
|
|
2
|
-
import {StyleSheet} from 'react-native-unistyles'
|
|
3
|
-
import BadgeStyles from '../theme/Badge.recipe'
|
|
2
|
+
import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
|
|
3
|
+
import {BadgeStyles, BadgeDefaultVariants} from '../theme/Badge.recipe'
|
|
4
4
|
import {ReactNode} from 'react'
|
|
5
|
+
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
6
|
+
import {HStack} from '../patterns'
|
|
5
7
|
|
|
6
8
|
type VeritcalPosition = 'top' | 'bottom'
|
|
7
9
|
type HorizontalPosition = 'left' | 'right'
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
type BadgeVariants = UnistylesVariants<typeof BadgeStyles>
|
|
12
|
+
|
|
13
|
+
type BadgeProps = BadgeVariants & {
|
|
14
|
+
colorPalette?: PalettesWithNestedKeys
|
|
12
15
|
content: number
|
|
13
16
|
max?: number
|
|
14
|
-
children
|
|
17
|
+
children?: ReactNode
|
|
15
18
|
x: HorizontalPosition
|
|
16
19
|
y: VeritcalPosition
|
|
17
20
|
backgroundColor?: string
|
|
@@ -20,51 +23,52 @@ interface BadgeProps {
|
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
const Badge = ({
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
colorPalette = 'accent',
|
|
27
|
+
variant = BadgeDefaultVariants.variant,
|
|
28
|
+
size = BadgeDefaultVariants.size,
|
|
25
29
|
content,
|
|
26
30
|
max,
|
|
27
31
|
children,
|
|
28
32
|
x,
|
|
29
33
|
y,
|
|
30
|
-
backgroundColor,
|
|
31
|
-
color,
|
|
32
34
|
mixins,
|
|
33
35
|
}: BadgeProps) => {
|
|
34
36
|
BadgeStyles.useVariants({
|
|
37
|
+
variant,
|
|
35
38
|
size,
|
|
36
|
-
colorPalette,
|
|
37
39
|
})
|
|
38
40
|
|
|
39
41
|
const displayedContent = max && content > max ? `${max}+` : content
|
|
40
42
|
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
const badgeSize = BadgeStyles.container(colorPalette).minWidth
|
|
45
|
+
const withoutChildrenSize = !children ? badgeSize : 'auto'
|
|
46
|
+
|
|
41
47
|
return (
|
|
42
|
-
<
|
|
43
|
-
{
|
|
48
|
+
<HStack
|
|
49
|
+
style={{
|
|
50
|
+
position: 'relative',
|
|
51
|
+
minWidth: withoutChildrenSize,
|
|
52
|
+
height: withoutChildrenSize,
|
|
53
|
+
}}>
|
|
54
|
+
{children && children}
|
|
44
55
|
<View
|
|
45
56
|
testID="varia-badge"
|
|
46
57
|
style={[
|
|
47
|
-
styles.badge(
|
|
48
|
-
|
|
49
|
-
y,
|
|
50
|
-
// resolvedBackgroundColor,
|
|
51
|
-
),
|
|
52
|
-
// style && styles.customStyle(style),
|
|
58
|
+
styles.badge(x, y),
|
|
59
|
+
BadgeStyles.container(colorPalette),
|
|
53
60
|
mixins && mixins,
|
|
54
61
|
]}>
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
<Text style={[styles.text, BadgeStyles.text(colorPalette)]}>
|
|
63
|
+
{displayedContent}
|
|
64
|
+
</Text>
|
|
57
65
|
</View>
|
|
58
|
-
</
|
|
66
|
+
</HStack>
|
|
59
67
|
)
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
const styles = StyleSheet.create({
|
|
63
|
-
badge: (
|
|
64
|
-
x,
|
|
65
|
-
y,
|
|
66
|
-
// backgroundColor,
|
|
67
|
-
) => ({
|
|
71
|
+
badge: (x, y) => ({
|
|
68
72
|
position: 'absolute',
|
|
69
73
|
[y]: 0,
|
|
70
74
|
[x]: 0,
|
|
@@ -76,17 +80,12 @@ const styles = StyleSheet.create({
|
|
|
76
80
|
paddingHorizontal: 6,
|
|
77
81
|
zIndex: 1,
|
|
78
82
|
borderRadius: 9999,
|
|
79
|
-
// backgroundColor,
|
|
80
83
|
borderWidth: 1,
|
|
81
84
|
alignItems: 'center',
|
|
82
85
|
justifyContent: 'center',
|
|
83
86
|
}),
|
|
84
87
|
text: {
|
|
85
|
-
fontSize: 12,
|
|
86
88
|
textAlign: 'center',
|
|
87
|
-
// variants: {
|
|
88
|
-
// colorScheme: variants.colorScheme(theme),
|
|
89
|
-
// },
|
|
90
89
|
},
|
|
91
90
|
customStyle: style => ({
|
|
92
91
|
...style,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {StyleProp, Text, TouchableOpacity, ViewStyle} from 'react-native'
|
|
2
2
|
import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
|
|
3
|
-
import {ButtonStyles,
|
|
4
|
-
import {
|
|
3
|
+
import {ButtonStyles, ButtonDefaultVariants} from '../theme/Button.recipe'
|
|
4
|
+
import {useMemo} from 'react'
|
|
5
5
|
import {IconWrapperProps} from './IconWrapper'
|
|
6
6
|
import Spinner from './Spinner'
|
|
7
|
-
|
|
8
|
-
// import { IconProps } from "../components/Icon";
|
|
9
|
-
|
|
10
|
-
type ButtonVariants = UnistylesVariants<typeof ButtonStyles>
|
|
7
|
+
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
11
8
|
|
|
12
9
|
type TextAdjustment = 'singleLine' | 'multiline' | 'adjustToFit'
|
|
13
10
|
|
|
11
|
+
type ButtonVariants = UnistylesVariants<typeof ButtonStyles>
|
|
12
|
+
|
|
14
13
|
type ButtonProps = ButtonVariants & {
|
|
14
|
+
colorPalette?: PalettesWithNestedKeys
|
|
15
15
|
text: string
|
|
16
16
|
onPress: () => void
|
|
17
17
|
loading?: boolean
|
|
@@ -19,21 +19,20 @@ type ButtonProps = ButtonVariants & {
|
|
|
19
19
|
maxWidth?: number | string
|
|
20
20
|
flex?: number
|
|
21
21
|
textAdjustment?: TextAdjustment
|
|
22
|
-
// style?: StyleProp<ViewStyle>;
|
|
23
|
-
// mixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[];
|
|
24
|
-
// customVariants?: CustomButtonVariants;
|
|
25
22
|
icon?: {
|
|
26
23
|
component: React.ComponentType<IconWrapperProps>
|
|
27
24
|
position: 'left' | 'right'
|
|
28
25
|
scale?: number
|
|
29
26
|
rotation?: number
|
|
27
|
+
size?: number
|
|
30
28
|
}
|
|
31
29
|
mixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
const Button = ({
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
colorPalette = 'accent',
|
|
34
|
+
size = ButtonDefaultVariants.size,
|
|
35
|
+
variant = ButtonDefaultVariants.variant,
|
|
37
36
|
onPress,
|
|
38
37
|
text,
|
|
39
38
|
loading = false,
|
|
@@ -46,7 +45,8 @@ const Button = ({
|
|
|
46
45
|
}: ButtonProps) => {
|
|
47
46
|
ButtonStyles.useVariants({
|
|
48
47
|
size,
|
|
49
|
-
|
|
48
|
+
variant,
|
|
49
|
+
disabled,
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
const getTextProps = useMemo(
|
|
@@ -68,8 +68,6 @@ const Button = ({
|
|
|
68
68
|
[textAdjustment],
|
|
69
69
|
)
|
|
70
70
|
|
|
71
|
-
const heightAuto = textAdjustment === 'multiline' ? 'auto' : null
|
|
72
|
-
|
|
73
71
|
const IconComponent = icon?.component
|
|
74
72
|
const IconRendered = IconComponent ? (
|
|
75
73
|
<IconComponent
|
|
@@ -78,7 +76,8 @@ const Button = ({
|
|
|
78
76
|
scale: icon.scale,
|
|
79
77
|
colorPalette,
|
|
80
78
|
//@ts-ignore
|
|
81
|
-
|
|
79
|
+
size: icon.size,
|
|
80
|
+
color: ButtonStyles.text(colorPalette).color,
|
|
82
81
|
}}
|
|
83
82
|
/>
|
|
84
83
|
) : null
|
|
@@ -86,8 +85,8 @@ const Button = ({
|
|
|
86
85
|
return (
|
|
87
86
|
<TouchableOpacity
|
|
88
87
|
style={[
|
|
89
|
-
styles.container(
|
|
90
|
-
ButtonStyles.container,
|
|
88
|
+
styles.container(flex, maxWidth),
|
|
89
|
+
ButtonStyles.container(colorPalette),
|
|
91
90
|
mixins && mixins,
|
|
92
91
|
]}
|
|
93
92
|
onPress={onPress}
|
|
@@ -102,7 +101,9 @@ const Button = ({
|
|
|
102
101
|
) : (
|
|
103
102
|
<>
|
|
104
103
|
{icon?.position === 'left' && IconRendered}
|
|
105
|
-
<Text
|
|
104
|
+
<Text
|
|
105
|
+
{...getTextProps()}
|
|
106
|
+
style={[styles.text, ButtonStyles.text(colorPalette)]}>
|
|
106
107
|
{text}
|
|
107
108
|
</Text>
|
|
108
109
|
{icon?.position === 'right' && IconRendered}
|
|
@@ -113,7 +114,7 @@ const Button = ({
|
|
|
113
114
|
}
|
|
114
115
|
|
|
115
116
|
const styles = StyleSheet.create({
|
|
116
|
-
container: (
|
|
117
|
+
container: (flex, maxWidth) => ({
|
|
117
118
|
flex,
|
|
118
119
|
maxWidth,
|
|
119
120
|
width: 'auto',
|
|
@@ -121,7 +122,6 @@ const styles = StyleSheet.create({
|
|
|
121
122
|
justifyContent: 'center',
|
|
122
123
|
alignItems: 'center',
|
|
123
124
|
flexShrink: 1,
|
|
124
|
-
opacity: disabled ? 0.6 : 1,
|
|
125
125
|
}),
|
|
126
126
|
text: {
|
|
127
127
|
textAlign: 'center',
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, {useCallback} from 'react'
|
|
2
|
+
import {View, Text, Pressable, StyleSheet} from 'react-native'
|
|
3
|
+
import {UnistylesVariants} from 'react-native-unistyles'
|
|
4
|
+
import {CheckboxDefaultVariants, CheckboxStyles} from '../theme/Checkbox.recipe'
|
|
5
|
+
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
6
|
+
import Svg, {Line} from 'react-native-svg'
|
|
7
|
+
|
|
8
|
+
type CheckboxVariants = UnistylesVariants<typeof CheckboxStyles>
|
|
9
|
+
|
|
10
|
+
type CheckboxProps = CheckboxVariants & {
|
|
11
|
+
children: React.ReactNode
|
|
12
|
+
colorPalette?: PalettesWithNestedKeys
|
|
13
|
+
checked: boolean
|
|
14
|
+
onCheckedChange: (checked: boolean) => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function Checkbox({
|
|
18
|
+
children,
|
|
19
|
+
checked,
|
|
20
|
+
onCheckedChange,
|
|
21
|
+
colorPalette = 'accent',
|
|
22
|
+
variant = CheckboxDefaultVariants.variant,
|
|
23
|
+
size = CheckboxDefaultVariants.size,
|
|
24
|
+
}: CheckboxProps) {
|
|
25
|
+
CheckboxStyles.useVariants({variant, size, checked})
|
|
26
|
+
|
|
27
|
+
const handlePress = useCallback(() => {
|
|
28
|
+
const newCheckedState = !checked
|
|
29
|
+
onCheckedChange(newCheckedState)
|
|
30
|
+
}, [checked, onCheckedChange])
|
|
31
|
+
|
|
32
|
+
const isChecked = checked
|
|
33
|
+
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
const checkSize = CheckboxStyles.check(colorPalette).width
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
const checkColor = CheckboxStyles.check(colorPalette).color
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Pressable
|
|
41
|
+
style={[styles.container, CheckboxStyles.container(colorPalette)]}
|
|
42
|
+
onPress={handlePress}>
|
|
43
|
+
<View
|
|
44
|
+
style={[
|
|
45
|
+
styles.checkContainer,
|
|
46
|
+
CheckboxStyles.checkContainer(colorPalette),
|
|
47
|
+
]}>
|
|
48
|
+
{isChecked && <Check size={checkSize} color={checkColor} />}
|
|
49
|
+
</View>
|
|
50
|
+
<Text style={CheckboxStyles.label(colorPalette)}>{children}</Text>
|
|
51
|
+
</Pressable>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const styles = StyleSheet.create({
|
|
56
|
+
container: {
|
|
57
|
+
flexDirection: 'row',
|
|
58
|
+
alignItems: 'center',
|
|
59
|
+
},
|
|
60
|
+
checkContainer: {
|
|
61
|
+
alignItems: 'center',
|
|
62
|
+
justifyContent: 'center',
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
export {Checkbox}
|
|
67
|
+
|
|
68
|
+
const Check = ({size, color}: {size: string; color: string}) => {
|
|
69
|
+
return (
|
|
70
|
+
<Svg
|
|
71
|
+
width={size}
|
|
72
|
+
height={size}
|
|
73
|
+
viewBox="0 0 16 13"
|
|
74
|
+
fill="none"
|
|
75
|
+
// @ts-ignore: svg props
|
|
76
|
+
xmlns="http://www.w3.org/2000/svg">
|
|
77
|
+
<Line
|
|
78
|
+
x1="1.64402"
|
|
79
|
+
y1="6.05591"
|
|
80
|
+
x2="7.41726"
|
|
81
|
+
y2="11.0638"
|
|
82
|
+
stroke={color}
|
|
83
|
+
strokeWidth="4"
|
|
84
|
+
/>
|
|
85
|
+
<Line
|
|
86
|
+
x1="4.69272"
|
|
87
|
+
y1="11.1604"
|
|
88
|
+
x2="13.8594"
|
|
89
|
+
y2="1.99377"
|
|
90
|
+
stroke={color}
|
|
91
|
+
strokeWidth="4"
|
|
92
|
+
/>
|
|
93
|
+
</Svg>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {useEffect} from 'react'
|
|
2
|
-
import {View, StyleSheet
|
|
1
|
+
import {useEffect, useLayoutEffect, useRef} from 'react'
|
|
2
|
+
import {View, StyleSheet} from 'react-native'
|
|
3
3
|
import Animated, {
|
|
4
4
|
Easing,
|
|
5
5
|
interpolate,
|
|
@@ -11,13 +11,15 @@ import Animated, {
|
|
|
11
11
|
import Svg, {Circle, G} from 'react-native-svg'
|
|
12
12
|
import {circleProgressTokens} from '../theme/CircleProgress.recipe'
|
|
13
13
|
import {withUnistyles} from 'react-native-unistyles'
|
|
14
|
+
import {resolveColor} from '../style/varia/utils'
|
|
15
|
+
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
14
16
|
|
|
15
17
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle)
|
|
16
|
-
|
|
18
|
+
const svgSize = 160
|
|
17
19
|
interface CircleProgressProps {
|
|
18
|
-
|
|
20
|
+
colorPalette?: PalettesWithNestedKeys
|
|
21
|
+
variant?: keyof typeof circleProgressTokens.variants.variant
|
|
19
22
|
size?: keyof typeof circleProgressTokens.variants.size
|
|
20
|
-
circleSize?: number
|
|
21
23
|
trackStrokeWidth?: number
|
|
22
24
|
progressStrokeWidth?: number
|
|
23
25
|
duration: number
|
|
@@ -27,13 +29,13 @@ interface CircleProgressProps {
|
|
|
27
29
|
rotationDirection?: 'clockwise' | 'counterclockwise'
|
|
28
30
|
children?: React.ReactNode
|
|
29
31
|
fontSize?: number | undefined
|
|
30
|
-
colors:
|
|
32
|
+
colors: any
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
const BaseCircleProgress = ({
|
|
34
|
-
|
|
36
|
+
colorPalette = 'accent',
|
|
37
|
+
variant = circleProgressTokens.defaultProps.variant,
|
|
35
38
|
size = circleProgressTokens.defaultProps.size,
|
|
36
|
-
circleSize,
|
|
37
39
|
trackStrokeWidth,
|
|
38
40
|
progressStrokeWidth,
|
|
39
41
|
duration,
|
|
@@ -44,40 +46,39 @@ const BaseCircleProgress = ({
|
|
|
44
46
|
children,
|
|
45
47
|
colors,
|
|
46
48
|
}: CircleProgressProps) => {
|
|
49
|
+
const container = useRef<View>(null)
|
|
50
|
+
|
|
51
|
+
// useLayoutEffect(() => {
|
|
52
|
+
// //@ts-ignore
|
|
53
|
+
// container.current?.measure((x, y, width, height) => {
|
|
54
|
+
// const pxPerUnit = width / svgSize
|
|
55
|
+
// const strokeWidthSVG =
|
|
56
|
+
// circleProgressTokens.variants.size[size]?.trackStrokeWidth * pxPerUnit
|
|
57
|
+
// })
|
|
58
|
+
// }, [])
|
|
59
|
+
|
|
47
60
|
const resolvedSize = circleProgressTokens.variants.size[size]
|
|
48
61
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
tokenColorKey.progressColor in colors
|
|
61
|
-
? colors[tokenColorKey.progressColor]
|
|
62
|
-
: tokenColorKey.progressColor
|
|
63
|
-
|
|
64
|
-
console.log('🚀 ~ tokenColorKey:', tokenColorKey)
|
|
65
|
-
|
|
66
|
-
circleSize =
|
|
67
|
-
circleSize ||
|
|
68
|
-
circleProgressTokens.variants.size[
|
|
69
|
-
size as keyof typeof circleProgressTokens.variants.size
|
|
70
|
-
]?.size
|
|
62
|
+
const colorValue = circleProgressTokens.variants.variant[variant]
|
|
63
|
+
const resolvedTrackColor = resolveColor(
|
|
64
|
+
colorValue.trackColor,
|
|
65
|
+
colors,
|
|
66
|
+
colorPalette,
|
|
67
|
+
)
|
|
68
|
+
const resolvedProgressColor = resolveColor(
|
|
69
|
+
colorValue.progressColor,
|
|
70
|
+
colors,
|
|
71
|
+
colorPalette,
|
|
72
|
+
)
|
|
71
73
|
|
|
72
74
|
trackStrokeWidth = trackStrokeWidth || resolvedSize?.trackStrokeWidth
|
|
73
75
|
progressStrokeWidth = progressStrokeWidth || resolvedSize?.progressStrokeWidth
|
|
74
76
|
|
|
75
77
|
const radius =
|
|
76
|
-
(
|
|
77
|
-
const circumference = 2 * Math.PI * radius
|
|
78
|
+
(svgSize! - Math.max(trackStrokeWidth!, progressStrokeWidth!)) / 2
|
|
79
|
+
const circumference = 2 * Math.PI * radius
|
|
78
80
|
|
|
79
|
-
|
|
80
|
-
const center = circleSize! / 2
|
|
81
|
+
const center = svgSize! / 2
|
|
81
82
|
|
|
82
83
|
const progress = useSharedValue(duration)
|
|
83
84
|
|
|
@@ -95,58 +96,45 @@ const BaseCircleProgress = ({
|
|
|
95
96
|
progressDirection === 'forward' ? duration : 0,
|
|
96
97
|
progressDirection === 'forward' ? 0 : duration,
|
|
97
98
|
],
|
|
98
|
-
[circumference, 0],
|
|
99
|
+
[circumference, 0],
|
|
99
100
|
Extrapolation.CLAMP,
|
|
100
101
|
)
|
|
101
102
|
return {
|
|
102
103
|
strokeDashoffset:
|
|
103
104
|
rotationDirection === 'clockwise'
|
|
104
105
|
? rStrokeDashOffset
|
|
105
|
-
: -rStrokeDashOffset,
|
|
106
|
+
: -rStrokeDashOffset,
|
|
106
107
|
}
|
|
107
108
|
})
|
|
108
109
|
|
|
109
110
|
return (
|
|
110
|
-
<View style={styles.container}>
|
|
111
|
+
<View style={styles.container} ref={container}>
|
|
111
112
|
<Svg
|
|
112
|
-
width="100%"
|
|
113
|
-
height="100%"
|
|
114
|
-
viewBox={`0 0 ${
|
|
113
|
+
width="100%"
|
|
114
|
+
height="100%"
|
|
115
|
+
viewBox={`0 0 ${svgSize} ${svgSize}`}
|
|
115
116
|
preserveAspectRatio="xMidYMid meet">
|
|
116
117
|
<G transform={`rotate(-90, ${center}, ${center})`}>
|
|
117
|
-
{/* Rotate to 12 o'clock */}
|
|
118
|
-
{/* Background Track */}
|
|
119
118
|
<Circle
|
|
120
|
-
cx={center}
|
|
121
|
-
cy={center}
|
|
122
|
-
r={radius}
|
|
123
|
-
stroke={
|
|
124
|
-
trackColor ? trackColor : resolvedTrackColor
|
|
125
|
-
// (trackColor as ColorValue) ||
|
|
126
|
-
// (resolvedType.trackColor
|
|
127
|
-
// ?.trackColor as ColorValue)
|
|
128
|
-
}
|
|
119
|
+
cx={center}
|
|
120
|
+
cy={center}
|
|
121
|
+
r={radius}
|
|
122
|
+
stroke={trackColor ? trackColor : resolvedTrackColor}
|
|
129
123
|
strokeWidth={trackStrokeWidth || resolvedSize?.trackStrokeWidth}
|
|
130
124
|
fill="transparent"
|
|
131
|
-
strokeDasharray={circumference}
|
|
125
|
+
strokeDasharray={circumference}
|
|
132
126
|
strokeLinecap="round"
|
|
133
127
|
/>
|
|
134
|
-
{/* Progress Stroke */}
|
|
135
128
|
<AnimatedCircle
|
|
136
|
-
cx={center}
|
|
137
|
-
cy={center}
|
|
138
|
-
r={radius}
|
|
139
|
-
stroke={
|
|
140
|
-
progressColor ? progressColor : resolvedProgressColor
|
|
141
|
-
// (progressColor as ColorValue) ||
|
|
142
|
-
// (resolvedType.progressColor
|
|
143
|
-
// ?.progressColor as ColorValue)
|
|
144
|
-
}
|
|
129
|
+
cx={center}
|
|
130
|
+
cy={center}
|
|
131
|
+
r={radius}
|
|
132
|
+
stroke={progressColor ? progressColor : resolvedProgressColor}
|
|
145
133
|
strokeWidth={
|
|
146
134
|
progressStrokeWidth || resolvedSize?.progressStrokeWidth
|
|
147
135
|
}
|
|
148
136
|
fill="transparent"
|
|
149
|
-
strokeDasharray={circumference}
|
|
137
|
+
strokeDasharray={circumference}
|
|
150
138
|
strokeLinecap="round"
|
|
151
139
|
animatedProps={animatedProps}></AnimatedCircle>
|
|
152
140
|
</G>
|
|
@@ -158,9 +146,8 @@ const BaseCircleProgress = ({
|
|
|
158
146
|
|
|
159
147
|
const styles = StyleSheet.create({
|
|
160
148
|
container: {
|
|
161
|
-
aspectRatio: 1,
|
|
162
|
-
|
|
163
|
-
// height: '100%', // Responsive height
|
|
149
|
+
aspectRatio: 1,
|
|
150
|
+
flex: 1,
|
|
164
151
|
},
|
|
165
152
|
childContainer: {
|
|
166
153
|
position: 'absolute',
|
|
@@ -178,3 +165,6 @@ const CircleProgress = withUnistyles(BaseCircleProgress, theme => ({
|
|
|
178
165
|
}))
|
|
179
166
|
|
|
180
167
|
export default CircleProgress
|
|
168
|
+
|
|
169
|
+
const clamp = (num: number, min: number, max: number) =>
|
|
170
|
+
Math.min(Math.max(num, min), max)
|