react-native-varia 0.2.3 → 0.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/bin/cli.js +24 -34
- package/lib/components/Accordion.tsx +113 -0
- package/lib/components/Button.tsx +16 -3
- package/lib/components/Checkbox.tsx +12 -7
- package/lib/components/CircleProgress.tsx +30 -21
- package/lib/components/Divider.tsx +23 -19
- package/lib/components/Drawer.tsx +23 -69
- package/lib/components/Field.tsx +24 -39
- package/lib/components/GradientBackground.tsx +25 -7
- package/lib/components/GradientText.tsx +61 -21
- package/lib/components/IconWrapper.tsx +20 -14
- package/lib/components/Input.tsx +107 -25
- package/lib/components/Modal.tsx +4 -10
- package/lib/components/NumberInput.tsx +54 -11
- package/lib/components/OldSlider.tsx +327 -0
- package/lib/components/RadioGroup.tsx +58 -18
- package/lib/components/ReText.tsx +1 -1
- package/lib/components/Select.tsx +58 -22
- package/lib/components/Slider.tsx +273 -138
- package/lib/components/Slideshow.tsx +65 -63
- package/lib/components/SlidingDrawer.tsx +20 -21
- package/lib/components/Spinner.tsx +13 -5
- package/lib/components/Toast.tsx +89 -0
- package/lib/components/context/Field.tsx +27 -0
- package/lib/patterns/index.tsx +16 -5
- package/lib/patterns/newPatterns.tsx +285 -0
- package/lib/theme/Button.recipe.tsx +11 -1
- package/lib/theme/CircleProgress.recipe.tsx +3 -3
- package/lib/theme/Drawer.recipe.tsx +107 -0
- package/lib/theme/Field.recipe.tsx +17 -2
- package/lib/theme/Input.recipe.tsx +12 -3
- package/lib/theme/NumberInput.recipe.tsx +8 -3
- package/lib/theme/RadioGroup.recipe.tsx +7 -1
- package/lib/theme/Select.recipe.tsx +7 -7
- package/lib/theme/Slider.recipe.tsx +402 -27
- package/lib/theme/Slideshow.recipe.tsx +1 -1
- package/lib/theme/Toast.recipe.tsx +71 -0
- package/lib/varia/mixins.ts +0 -4
- package/lib/varia/types.ts +8 -0
- package/lib/varia/utils.ts +66 -0
- package/package.json +1 -1
- package/lib/theme/Button.recipe-old.tsx +0 -67
- package/lib/theme/SlidingDrawer.recipe.tsx +0 -53
package/bin/cli.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { program } = require("commander");
|
|
4
4
|
const inquirer = require("inquirer");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const fs = require("fs-extra");
|
|
7
7
|
|
|
8
|
-
// 🔹 Dependencias entre componentes
|
|
9
8
|
const COMPONENT_DEPENDENCIES = {
|
|
10
9
|
Button: ["Spinner", "IconWrapper"],
|
|
11
10
|
Field: ["Text"],
|
|
@@ -19,9 +18,18 @@ const ICON_DEPENDENCIES = {
|
|
|
19
18
|
NumberInput: ["Plus", "Minus"],
|
|
20
19
|
};
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
const CONTEXT_DEPENDENCIES = {
|
|
22
|
+
Field: true
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function copyContextComponentIfNeeded(component, destComponents, overwrite = true) {
|
|
26
|
+
if (!CONTEXT_DEPENDENCIES[component]) return;
|
|
27
|
+
|
|
28
|
+
const contextSrc = path.join(COMPONENTS_DIR, "context", `${component}.tsx`);
|
|
29
|
+
const contextDest = path.join(process.cwd(), destComponents, "context", `${component}.tsx`);
|
|
30
|
+
copyFile(contextSrc, contextDest, `Context de "${component}"`, overwrite);
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
function resolveDependencies(component, seen = new Set()) {
|
|
26
34
|
if (seen.has(component)) return [];
|
|
27
35
|
seen.add(component);
|
|
@@ -36,21 +44,14 @@ function resolveDependencies(component, seen = new Set()) {
|
|
|
36
44
|
return [...new Set(allDeps)];
|
|
37
45
|
}
|
|
38
46
|
|
|
39
|
-
// Carpetas base
|
|
40
47
|
const COMPONENTS_DIR = path.join(__dirname, "../lib/components");
|
|
41
48
|
const THEME_DIR = path.join(__dirname, "../lib/theme");
|
|
42
49
|
|
|
43
|
-
/**
|
|
44
|
-
* Obtiene la lista de todos los componentes disponibles en la librería.
|
|
45
|
-
*/
|
|
46
50
|
function getAvailableComponents() {
|
|
47
51
|
if (!fs.existsSync(COMPONENTS_DIR)) return [];
|
|
48
52
|
return fs.readdirSync(COMPONENTS_DIR).map((name) => path.parse(name).name);
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
/**
|
|
52
|
-
* Copia un archivo desde origen a destino.
|
|
53
|
-
*/
|
|
54
55
|
function copyFile(srcPath, destPath, label, overwrite = true) {
|
|
55
56
|
if (!fs.existsSync(srcPath)) {
|
|
56
57
|
console.warn(`⚠️ ${label} no encontrado: ${srcPath}`);
|
|
@@ -73,9 +74,6 @@ function copyFile(srcPath, destPath, label, overwrite = true) {
|
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
/**
|
|
77
|
-
* Copia un componente y su recipe.
|
|
78
|
-
*/
|
|
79
77
|
function copyComponentAndRecipe(component, destComponents, destTheme, overwrite = true) {
|
|
80
78
|
const componentSrc = path.join(COMPONENTS_DIR, `${component}.tsx`);
|
|
81
79
|
const componentDest = path.join(process.cwd(), destComponents, `${component}.tsx`);
|
|
@@ -86,9 +84,6 @@ function copyComponentAndRecipe(component, destComponents, destTheme, overwrite
|
|
|
86
84
|
copyFile(recipeSrc, recipeDest, `Recipe de "${component}"`, overwrite);
|
|
87
85
|
}
|
|
88
86
|
|
|
89
|
-
/**
|
|
90
|
-
* Pregunta si se desea sobrescribir componentes existentes.
|
|
91
|
-
*/
|
|
92
87
|
async function confirmOverwrite(existingComponents) {
|
|
93
88
|
const { overwrite } = await inquirer.prompt([
|
|
94
89
|
{
|
|
@@ -119,12 +114,10 @@ program
|
|
|
119
114
|
const patternsDest = path.join(process.cwd(), "src/patterns");
|
|
120
115
|
|
|
121
116
|
try {
|
|
122
|
-
// Copiar varia
|
|
123
117
|
fs.ensureDirSync(path.dirname(variaDest));
|
|
124
118
|
fs.copySync(variaSrc, variaDest, { overwrite: true });
|
|
125
119
|
console.log(`✅ Carpeta "varia" copiada a ${variaDest}`);
|
|
126
120
|
|
|
127
|
-
// Copiar patterns
|
|
128
121
|
fs.ensureDirSync(path.dirname(patternsDest));
|
|
129
122
|
fs.copySync(patternsSrc, patternsDest, { overwrite: true });
|
|
130
123
|
console.log(`✅ Carpeta "patterns" copiada a ${patternsDest}`);
|
|
@@ -233,9 +226,8 @@ program
|
|
|
233
226
|
(c) => c.charAt(0).toUpperCase() + c.slice(1)
|
|
234
227
|
);
|
|
235
228
|
|
|
236
|
-
// 🔹 Obtener dependencias totales
|
|
237
229
|
const allComponents = new Set();
|
|
238
|
-
const componentToDeps = {};
|
|
230
|
+
const componentToDeps = {};
|
|
239
231
|
for (const c of componentsCapitalized) {
|
|
240
232
|
const deps = resolveDependencies(c);
|
|
241
233
|
componentToDeps[c] = deps;
|
|
@@ -245,7 +237,6 @@ program
|
|
|
245
237
|
|
|
246
238
|
const allComponentsArray = Array.from(allComponents);
|
|
247
239
|
|
|
248
|
-
// 🔹 Validar existencia
|
|
249
240
|
const notFound = allComponentsArray.filter((c) => !available.includes(c));
|
|
250
241
|
if (notFound.length > 0) {
|
|
251
242
|
console.error(`❌ Los siguientes componentes no existen: ${notFound.join(", ")}`);
|
|
@@ -254,12 +245,18 @@ program
|
|
|
254
245
|
process.exit(1);
|
|
255
246
|
}
|
|
256
247
|
|
|
257
|
-
|
|
248
|
+
function copyContextComponentIfNeeded(component, destComponents, overwrite = true) {
|
|
249
|
+
if (!CONTEXT_DEPENDENCIES[component]) return;
|
|
250
|
+
|
|
251
|
+
const contextSrc = path.join(COMPONENTS_DIR, "context", `${component}.tsx`);
|
|
252
|
+
const contextDest = path.join(process.cwd(), destComponents, "context", `${component}.tsx`);
|
|
253
|
+
copyFile(contextSrc, contextDest, `Context de "${component}"`, overwrite);
|
|
254
|
+
}
|
|
255
|
+
|
|
258
256
|
for (const mainComponent of componentsCapitalized) {
|
|
259
257
|
const componentPath = path.join(process.cwd(), options.dest, `${mainComponent}.tsx`);
|
|
260
258
|
let overwriteMain = true;
|
|
261
259
|
|
|
262
|
-
// Preguntar solo si el componente principal existe
|
|
263
260
|
if (fs.existsSync(componentPath)) {
|
|
264
261
|
const { overwrite } = await inquirer.prompt([
|
|
265
262
|
{
|
|
@@ -276,10 +273,10 @@ program
|
|
|
276
273
|
}
|
|
277
274
|
}
|
|
278
275
|
|
|
279
|
-
// 🔹 Copiar componente principal
|
|
280
276
|
copyComponentAndRecipe(mainComponent, options.dest, options.theme, overwriteMain);
|
|
281
277
|
|
|
282
|
-
|
|
278
|
+
copyContextComponentIfNeeded(mainComponent, options.dest, overwriteMain);
|
|
279
|
+
|
|
283
280
|
const deps = componentToDeps[mainComponent] || [];
|
|
284
281
|
for (const dep of deps) {
|
|
285
282
|
const depPath = path.join(process.cwd(), options.dest, `${dep}.tsx`);
|
|
@@ -291,7 +288,6 @@ program
|
|
|
291
288
|
copyComponentAndRecipe(dep, options.dest, options.theme, true);
|
|
292
289
|
}
|
|
293
290
|
|
|
294
|
-
// 🔹 Copiar íconos dependientes
|
|
295
291
|
const iconDeps = ICON_DEPENDENCIES[mainComponent] || [];
|
|
296
292
|
if (iconDeps.length > 0) {
|
|
297
293
|
console.log(`🎨 Añadiendo íconos requeridos por "${mainComponent}": ${iconDeps.join(", ")}`);
|
|
@@ -305,7 +301,6 @@ program
|
|
|
305
301
|
copyIconTemplate(iconName, options.icons);
|
|
306
302
|
}
|
|
307
303
|
|
|
308
|
-
// Asegurar que IconWrapper esté disponible
|
|
309
304
|
ensureIconWrapper(options.dest, options.theme);
|
|
310
305
|
}
|
|
311
306
|
}
|
|
@@ -336,9 +331,6 @@ function copyIconTemplate(iconName, dest) {
|
|
|
336
331
|
}
|
|
337
332
|
}
|
|
338
333
|
|
|
339
|
-
/**
|
|
340
|
-
* Copia IconWrapper si no existe en la app
|
|
341
|
-
*/
|
|
342
334
|
function ensureIconWrapper(destComponents, destTheme) {
|
|
343
335
|
const wrapperComponentDest = path.join(process.cwd(), destComponents, "IconWrapper.tsx");
|
|
344
336
|
const wrapperRecipeDest = path.join(process.cwd(), destTheme, "IconWrapper.recipe.tsx");
|
|
@@ -363,7 +355,6 @@ function ensureIconWrapper(destComponents, destTheme) {
|
|
|
363
355
|
}
|
|
364
356
|
}
|
|
365
357
|
|
|
366
|
-
// Comando CLI: add-icon
|
|
367
358
|
program
|
|
368
359
|
.command("add-icon [iconName]")
|
|
369
360
|
.description("Copia un icono basado en la plantilla Icon.tsx")
|
|
@@ -381,7 +372,6 @@ program
|
|
|
381
372
|
const finalName = rawName.charAt(0).toUpperCase() + rawName.slice(1);
|
|
382
373
|
const destPath = path.join(process.cwd(), options.dest, `${finalName}.tsx`);
|
|
383
374
|
|
|
384
|
-
// 🔹 Si ya existe, preguntar antes de sobrescribir
|
|
385
375
|
if (fs.existsSync(destPath)) {
|
|
386
376
|
const { overwrite } = await inquirer.prompt([
|
|
387
377
|
{
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React, {ReactNode, useState} from 'react'
|
|
2
|
+
import {View, Pressable} from 'react-native'
|
|
3
|
+
import Animated from 'react-native-reanimated'
|
|
4
|
+
import {LinearTransition} from 'react-native-reanimated'
|
|
5
|
+
import {StyleSheet} from 'react-native-unistyles'
|
|
6
|
+
import Text from './Text'
|
|
7
|
+
|
|
8
|
+
type AccordionItemProps = {
|
|
9
|
+
title: string
|
|
10
|
+
itemKey: string
|
|
11
|
+
children: ReactNode
|
|
12
|
+
isOpen?: boolean
|
|
13
|
+
onToggle?: () => void
|
|
14
|
+
scrollViewRef?: any
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type AccordionGroupRootProps = {
|
|
18
|
+
children: ReactNode
|
|
19
|
+
defaultOpenKeys?: string[]
|
|
20
|
+
allowMultiple?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const AccordionGroup = {
|
|
24
|
+
Root: AccordionGroupRoot,
|
|
25
|
+
Item: AccordionGroupItem,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function AccordionGroupRoot({
|
|
29
|
+
children,
|
|
30
|
+
defaultOpenKeys = [],
|
|
31
|
+
allowMultiple = false,
|
|
32
|
+
}: AccordionGroupRootProps) {
|
|
33
|
+
const [openKeys, setOpenKeys] = useState<Set<string>>(
|
|
34
|
+
() => new Set(defaultOpenKeys),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
const toggleItem = (key: string) => {
|
|
38
|
+
setOpenKeys(prev => {
|
|
39
|
+
const newSet = new Set(prev)
|
|
40
|
+
if (newSet.has(key)) {
|
|
41
|
+
newSet.delete(key)
|
|
42
|
+
} else {
|
|
43
|
+
if (allowMultiple) {
|
|
44
|
+
newSet.add(key)
|
|
45
|
+
} else {
|
|
46
|
+
return new Set([key])
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return newSet
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const items = React.Children.map(children, child => {
|
|
54
|
+
if (!React.isValidElement(child)) return child
|
|
55
|
+
const cp = child.props as AccordionItemProps
|
|
56
|
+
const key = cp.itemKey
|
|
57
|
+
const isOpen = openKeys.has(key)
|
|
58
|
+
return React.cloneElement(child, {
|
|
59
|
+
isOpen,
|
|
60
|
+
onToggle: () => toggleItem(key),
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
return <View style={styles.groupContainer}>{items}</View>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function AccordionGroupItem({
|
|
68
|
+
title,
|
|
69
|
+
children,
|
|
70
|
+
isOpen = false,
|
|
71
|
+
onToggle,
|
|
72
|
+
}: AccordionItemProps) {
|
|
73
|
+
return (
|
|
74
|
+
<Animated.View
|
|
75
|
+
// Aquí aplicas la transición de layout
|
|
76
|
+
layout={LinearTransition.duration(150)}
|
|
77
|
+
style={styles.itemContainer}>
|
|
78
|
+
<Pressable onPress={onToggle} style={styles.header}>
|
|
79
|
+
<Text style={styles.headerText}>{title}</Text>
|
|
80
|
+
</Pressable>
|
|
81
|
+
|
|
82
|
+
{isOpen && (
|
|
83
|
+
<View style={styles.contentContainer}>
|
|
84
|
+
<View style={styles.innerContent}>{children}</View>
|
|
85
|
+
</View>
|
|
86
|
+
)}
|
|
87
|
+
</Animated.View>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const styles = StyleSheet.create({
|
|
92
|
+
groupContainer: {},
|
|
93
|
+
itemContainer: {
|
|
94
|
+
borderWidth: 1,
|
|
95
|
+
borderColor: '#ddd',
|
|
96
|
+
borderRadius: 6,
|
|
97
|
+
marginVertical: 8,
|
|
98
|
+
overflow: 'hidden', // importante para que no se vea contenido fuera
|
|
99
|
+
},
|
|
100
|
+
header: {
|
|
101
|
+
padding: 12,
|
|
102
|
+
backgroundColor: '#f0f0f0',
|
|
103
|
+
},
|
|
104
|
+
headerText: {
|
|
105
|
+
fontSize: 16,
|
|
106
|
+
},
|
|
107
|
+
contentContainer: {
|
|
108
|
+
// no necesitamos animar altura manual, lo hace el layout
|
|
109
|
+
},
|
|
110
|
+
innerContent: {
|
|
111
|
+
padding: 12,
|
|
112
|
+
},
|
|
113
|
+
})
|
|
@@ -5,11 +5,18 @@ import {useMemo} from 'react'
|
|
|
5
5
|
import {IconWrapperProps} from './IconWrapper'
|
|
6
6
|
import Spinner, {SpinnerProps} from './Spinner'
|
|
7
7
|
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
8
|
+
import { getVariantValue } from '../style/varia/utils'
|
|
8
9
|
|
|
9
10
|
type TextAdjustment = 'singleLine' | 'multiline' | 'adjustToFit'
|
|
10
11
|
|
|
11
12
|
type ButtonVariants = UnistylesVariants<typeof ButtonStyles>
|
|
12
13
|
|
|
14
|
+
interface TextAdjustmentProps {
|
|
15
|
+
adjustsFontSizeToFit?: boolean
|
|
16
|
+
numberOfLines?: number
|
|
17
|
+
ellipsizeMode?: 'tail' | 'head' | 'middle' | 'clip'
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
type ButtonProps = ButtonVariants & {
|
|
14
21
|
colorPalette?: PalettesWithNestedKeys
|
|
15
22
|
text?: string
|
|
@@ -27,6 +34,7 @@ type ButtonProps = ButtonVariants & {
|
|
|
27
34
|
size?: number
|
|
28
35
|
}
|
|
29
36
|
mixins?: StyleProp<ViewStyle> | StyleProp<ViewStyle>[]
|
|
37
|
+
style?: StyleProp<ViewStyle>
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
const Button = ({
|
|
@@ -42,15 +50,17 @@ const Button = ({
|
|
|
42
50
|
textAdjustment = 'singleLine',
|
|
43
51
|
icon,
|
|
44
52
|
mixins,
|
|
53
|
+
style,
|
|
45
54
|
}: ButtonProps) => {
|
|
46
55
|
ButtonStyles.useVariants({
|
|
47
56
|
size,
|
|
48
57
|
variant,
|
|
49
58
|
disabled,
|
|
50
59
|
})
|
|
60
|
+
console.log("🚀 ~ size:", size)
|
|
51
61
|
|
|
52
62
|
const getTextProps = useMemo(
|
|
53
|
-
() => ():
|
|
63
|
+
() => (): TextAdjustmentProps => {
|
|
54
64
|
switch (textAdjustment) {
|
|
55
65
|
case 'adjustToFit':
|
|
56
66
|
return {adjustsFontSizeToFit: true, numberOfLines: 1}
|
|
@@ -68,6 +78,8 @@ const Button = ({
|
|
|
68
78
|
[textAdjustment],
|
|
69
79
|
)
|
|
70
80
|
|
|
81
|
+
const resolvedColor = getVariantValue(ButtonStyles.text(colorPalette), 'variant', variant, 'color')
|
|
82
|
+
|
|
71
83
|
const IconComponent = icon?.component
|
|
72
84
|
const IconRendered = IconComponent ? (
|
|
73
85
|
<IconComponent
|
|
@@ -76,7 +88,7 @@ const Button = ({
|
|
|
76
88
|
scale: icon.scale,
|
|
77
89
|
colorPalette,
|
|
78
90
|
size: icon.size,
|
|
79
|
-
color:
|
|
91
|
+
color: resolvedColor,
|
|
80
92
|
}}
|
|
81
93
|
/>
|
|
82
94
|
) : null
|
|
@@ -87,13 +99,14 @@ const Button = ({
|
|
|
87
99
|
styles.container(flex, maxWidth),
|
|
88
100
|
ButtonStyles.container(colorPalette),
|
|
89
101
|
mixins && mixins,
|
|
102
|
+
style,
|
|
90
103
|
]}
|
|
91
104
|
onPress={onPress}
|
|
92
105
|
disabled={disabled || loading}>
|
|
93
106
|
{loading ? (
|
|
94
107
|
<Spinner
|
|
95
108
|
size={size as SpinnerProps['size']}
|
|
96
|
-
color={
|
|
109
|
+
color={resolvedColor}
|
|
97
110
|
/>
|
|
98
111
|
) : (
|
|
99
112
|
<>
|
|
@@ -4,6 +4,7 @@ import {UnistylesVariants} from 'react-native-unistyles'
|
|
|
4
4
|
import {CheckboxDefaultVariants, CheckboxStyles} from '../theme/Checkbox.recipe'
|
|
5
5
|
import {PalettesWithNestedKeys} from '../style/varia/types'
|
|
6
6
|
import Svg, {Line} from 'react-native-svg'
|
|
7
|
+
import { getVariantValue } from '../style/varia/utils'
|
|
7
8
|
|
|
8
9
|
type CheckboxVariants = UnistylesVariants<typeof CheckboxStyles>
|
|
9
10
|
|
|
@@ -31,12 +32,16 @@ function Checkbox({
|
|
|
31
32
|
|
|
32
33
|
const isChecked = checked
|
|
33
34
|
|
|
34
|
-
const checkStyle = CheckboxStyles.check(colorPalette) as {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
const checkSize = checkStyle.width
|
|
39
|
-
const checkColor = checkStyle.color
|
|
35
|
+
// const checkStyle = CheckboxStyles.check(colorPalette) as {
|
|
36
|
+
// width: string
|
|
37
|
+
// color: string
|
|
38
|
+
// }
|
|
39
|
+
// const checkSize = checkStyle.width
|
|
40
|
+
// const checkColor = checkStyle.color
|
|
41
|
+
|
|
42
|
+
const checkColor = getVariantValue(CheckboxStyles.check(colorPalette), 'variant', variant, 'color')
|
|
43
|
+
const checkSize = getVariantValue(CheckboxStyles.check(colorPalette), 'size', size, 'width')
|
|
44
|
+
|
|
40
45
|
|
|
41
46
|
return (
|
|
42
47
|
<Pressable
|
|
@@ -65,7 +70,7 @@ const styles = StyleSheet.create({
|
|
|
65
70
|
},
|
|
66
71
|
})
|
|
67
72
|
|
|
68
|
-
export
|
|
73
|
+
export default Checkbox
|
|
69
74
|
|
|
70
75
|
const Check = ({size, color}: {size: string; color: string}) => {
|
|
71
76
|
return (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {useEffect} from 'react'
|
|
2
|
-
import {View,
|
|
2
|
+
import {TextStyle, View, ViewStyle} from 'react-native'
|
|
3
3
|
import Animated, {
|
|
4
4
|
Easing,
|
|
5
5
|
interpolate,
|
|
@@ -10,9 +10,15 @@ import Animated, {
|
|
|
10
10
|
} from 'react-native-reanimated'
|
|
11
11
|
import Svg, {Circle, G} from 'react-native-svg'
|
|
12
12
|
import {circleProgressTokens} from '../theme/CircleProgress.recipe'
|
|
13
|
-
import {withUnistyles} from 'react-native-unistyles'
|
|
13
|
+
import {withUnistyles, StyleSheet} from 'react-native-unistyles'
|
|
14
14
|
import {resolveColor} from '../style/varia/utils'
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
NestedColorsType,
|
|
17
|
+
PalettesWithNestedKeys,
|
|
18
|
+
progressDirection,
|
|
19
|
+
rotationDirection,
|
|
20
|
+
ThemeType,
|
|
21
|
+
} from '../style/varia/types'
|
|
16
22
|
import {SharedValue} from 'react-native-reanimated'
|
|
17
23
|
|
|
18
24
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle)
|
|
@@ -22,17 +28,19 @@ interface CircleProgressProps {
|
|
|
22
28
|
variant?: keyof typeof circleProgressTokens.variants.variant
|
|
23
29
|
size?: keyof typeof circleProgressTokens.variants.size
|
|
24
30
|
trackStrokeWidth?: number
|
|
25
|
-
progress: SharedValue<number>
|
|
26
|
-
|
|
31
|
+
progress: SharedValue<number>
|
|
27
32
|
progressStrokeWidth?: number
|
|
28
33
|
duration: number
|
|
29
34
|
trackColor?: string
|
|
30
35
|
progressColor?: string
|
|
31
|
-
progressDirection?:
|
|
32
|
-
rotationDirection?:
|
|
36
|
+
progressDirection?: progressDirection
|
|
37
|
+
rotationDirection?: rotationDirection
|
|
33
38
|
children?: React.ReactNode
|
|
34
|
-
fontSize?:
|
|
35
|
-
colors:
|
|
39
|
+
fontSize?: TextStyle['fontSize']
|
|
40
|
+
colors: NestedColorsType
|
|
41
|
+
flex?: ViewStyle['flex']
|
|
42
|
+
width?: ViewStyle['width']
|
|
43
|
+
height?: ViewStyle['height']
|
|
36
44
|
}
|
|
37
45
|
|
|
38
46
|
const BaseCircleProgress = ({
|
|
@@ -49,6 +57,9 @@ const BaseCircleProgress = ({
|
|
|
49
57
|
rotationDirection = 'clockwise',
|
|
50
58
|
children,
|
|
51
59
|
colors,
|
|
60
|
+
flex = 1,
|
|
61
|
+
width = '100%',
|
|
62
|
+
height,
|
|
52
63
|
}: CircleProgressProps) => {
|
|
53
64
|
const resolvedSize = circleProgressTokens.variants.size[size]
|
|
54
65
|
|
|
@@ -106,7 +117,7 @@ const BaseCircleProgress = ({
|
|
|
106
117
|
})
|
|
107
118
|
|
|
108
119
|
return (
|
|
109
|
-
<View style={styles.container}>
|
|
120
|
+
<View style={styles.container(flex, width, height)}>
|
|
110
121
|
<Svg
|
|
111
122
|
width="100%"
|
|
112
123
|
height="100%"
|
|
@@ -143,16 +154,17 @@ const BaseCircleProgress = ({
|
|
|
143
154
|
}
|
|
144
155
|
|
|
145
156
|
const styles = StyleSheet.create({
|
|
146
|
-
container:
|
|
157
|
+
container: (
|
|
158
|
+
flex: ViewStyle['flex'],
|
|
159
|
+
width: ViewStyle['width'],
|
|
160
|
+
height: ViewStyle['height'],
|
|
161
|
+
) => ({
|
|
147
162
|
aspectRatio: 1,
|
|
148
|
-
flex
|
|
149
|
-
|
|
163
|
+
flex,
|
|
164
|
+
maxWidth: width,
|
|
165
|
+
maxHeight: height,
|
|
166
|
+
}),
|
|
150
167
|
childContainer: {
|
|
151
|
-
position: 'absolute',
|
|
152
|
-
top: 0,
|
|
153
|
-
left: 0,
|
|
154
|
-
right: 0,
|
|
155
|
-
bottom: 0,
|
|
156
168
|
justifyContent: 'center',
|
|
157
169
|
alignItems: 'center',
|
|
158
170
|
},
|
|
@@ -163,6 +175,3 @@ const CircleProgress = withUnistyles(BaseCircleProgress, theme => ({
|
|
|
163
175
|
}))
|
|
164
176
|
|
|
165
177
|
export default CircleProgress
|
|
166
|
-
|
|
167
|
-
const clamp = (num: number, min: number, max: number) =>
|
|
168
|
-
Math.min(Math.max(num, min), max)
|
|
@@ -1,43 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import {View} from 'react-native'
|
|
2
|
+
import {StyleSheet} from 'react-native-unistyles'
|
|
3
|
+
import {PalettesWithNestedKeys, ThemeColors} from '../style/varia/types'
|
|
4
|
+
import {resolveColor} from '../style/varia/utils'
|
|
4
5
|
|
|
5
6
|
const Divider = ({
|
|
6
7
|
color,
|
|
7
8
|
size = 1,
|
|
8
9
|
axis = 'y',
|
|
9
10
|
margin = 0,
|
|
11
|
+
colorPalette = 'accent',
|
|
10
12
|
}: {
|
|
11
|
-
color?:
|
|
12
|
-
size?: number
|
|
13
|
-
axis?: 'x' | 'y'
|
|
14
|
-
margin?: number
|
|
13
|
+
color?: ThemeColors
|
|
14
|
+
size?: number
|
|
15
|
+
axis?: 'x' | 'y'
|
|
16
|
+
margin?: number
|
|
17
|
+
colorPalette?: PalettesWithNestedKeys
|
|
15
18
|
}) => {
|
|
16
19
|
return (
|
|
17
20
|
<View style={styles.container(size, axis, margin)}>
|
|
18
|
-
<View style={[styles.divider(color, size, axis)]} />
|
|
21
|
+
<View style={[styles.divider(color, colorPalette, size, axis)]} />
|
|
19
22
|
</View>
|
|
20
|
-
)
|
|
21
|
-
}
|
|
23
|
+
)
|
|
24
|
+
}
|
|
22
25
|
|
|
23
26
|
const styles = StyleSheet.create(theme => ({
|
|
24
27
|
container: (size, axis, margin) => ({
|
|
25
28
|
flex: 1,
|
|
29
|
+
alignSelf: 'stretch',
|
|
26
30
|
flexDirection: 'row',
|
|
27
31
|
alignItems: 'center',
|
|
28
32
|
justifyContent: 'center',
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
maxWidth: axis === 'y' ? size : '100%',
|
|
34
|
+
maxHeight: axis === 'x' ? size : '100%',
|
|
31
35
|
marginHorizontal: axis === 'x' ? margin : 0,
|
|
32
36
|
marginVertical: axis === 'y' ? margin : 0,
|
|
33
37
|
}),
|
|
34
|
-
divider: (color, size, axis) => ({
|
|
35
|
-
width: axis === '
|
|
36
|
-
height: axis === '
|
|
38
|
+
divider: (color, colorPalette, size, axis) => ({
|
|
39
|
+
width: axis === 'y' ? size : '100%',
|
|
40
|
+
height: axis === 'x' ? size : '100%',
|
|
37
41
|
backgroundColor: color
|
|
38
|
-
? color
|
|
39
|
-
: theme.colors.
|
|
42
|
+
? resolveColor(color, theme.colors, colorPalette)
|
|
43
|
+
: theme.colors.fg.default,
|
|
40
44
|
}),
|
|
41
|
-
}))
|
|
45
|
+
}))
|
|
42
46
|
|
|
43
|
-
export default Divider
|
|
47
|
+
export default Divider
|