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.
package/bin/cli.js CHANGED
@@ -1,9 +1,41 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { program } = require("commander");
4
+ const inquirer = require("inquirer");
4
5
  const path = require("path");
5
6
  const fs = require("fs-extra");
6
7
 
8
+ // 🔹 Dependencias entre componentes
9
+ const COMPONENT_DEPENDENCIES = {
10
+ Button: ["Spinner", "IconWrapper"],
11
+ Field: ["Text"],
12
+ Link: ["Text"],
13
+ Modal: ["Text"],
14
+ ReText: ["Text"],
15
+ Select: ["Text"],
16
+ };
17
+
18
+ const ICON_DEPENDENCIES = {
19
+ NumberInput: ["Plus", "Minus"],
20
+ };
21
+
22
+ /**
23
+ * Obtiene todas las dependencias de un componente de forma recursiva.
24
+ */
25
+ function resolveDependencies(component, seen = new Set()) {
26
+ if (seen.has(component)) return [];
27
+ seen.add(component);
28
+
29
+ const deps = COMPONENT_DEPENDENCIES[component] || [];
30
+ let allDeps = [...deps];
31
+
32
+ for (const dep of deps) {
33
+ allDeps = [...allDeps, ...resolveDependencies(dep, seen)];
34
+ }
35
+
36
+ return [...new Set(allDeps)];
37
+ }
38
+
7
39
  // Carpetas base
8
40
  const COMPONENTS_DIR = path.join(__dirname, "../lib/components");
9
41
  const THEME_DIR = path.join(__dirname, "../lib/theme");
@@ -19,14 +51,20 @@ function getAvailableComponents() {
19
51
  /**
20
52
  * Copia un archivo desde origen a destino.
21
53
  */
22
- function copyFile(srcPath, destPath, label) {
54
+ function copyFile(srcPath, destPath, label, overwrite = true) {
23
55
  if (!fs.existsSync(srcPath)) {
24
56
  console.warn(`⚠️ ${label} no encontrado: ${srcPath}`);
25
57
  return false;
26
58
  }
27
59
  try {
28
- fs.ensureDirSync(path.dirname(destPath)); // crea carpeta destino si no existe
29
- fs.copySync(srcPath, destPath, { overwrite: true, errorOnExist: false });
60
+ fs.ensureDirSync(path.dirname(destPath));
61
+
62
+ if (!overwrite && fs.existsSync(destPath)) {
63
+ console.log(`⏭️ Saltando ${label}, ya existe en ${destPath}`);
64
+ return false;
65
+ }
66
+
67
+ fs.copySync(srcPath, destPath, { overwrite: true });
30
68
  console.log(`✅ ${label} copiado a: ${destPath}`);
31
69
  return true;
32
70
  } catch (err) {
@@ -38,14 +76,31 @@ function copyFile(srcPath, destPath, label) {
38
76
  /**
39
77
  * Copia un componente y su recipe.
40
78
  */
41
- function copyComponentAndRecipe(component, destComponents, destTheme) {
79
+ function copyComponentAndRecipe(component, destComponents, destTheme, overwrite = true) {
42
80
  const componentSrc = path.join(COMPONENTS_DIR, `${component}.tsx`);
43
81
  const componentDest = path.join(process.cwd(), destComponents, `${component}.tsx`);
44
- copyFile(componentSrc, componentDest, `Componente "${component}"`);
82
+ copyFile(componentSrc, componentDest, `Componente "${component}"`, overwrite);
45
83
 
46
84
  const recipeSrc = path.join(THEME_DIR, `${component}.recipe.tsx`);
47
85
  const recipeDest = path.join(process.cwd(), destTheme, `${component}.recipe.tsx`);
48
- copyFile(recipeSrc, recipeDest, `Recipe de "${component}"`);
86
+ copyFile(recipeSrc, recipeDest, `Recipe de "${component}"`, overwrite);
87
+ }
88
+
89
+ /**
90
+ * Pregunta si se desea sobrescribir componentes existentes.
91
+ */
92
+ async function confirmOverwrite(existingComponents) {
93
+ const { overwrite } = await inquirer.prompt([
94
+ {
95
+ type: "confirm",
96
+ name: "overwrite",
97
+ message: `Los siguientes componentes ya existen: ${existingComponents.join(
98
+ ", "
99
+ )}\n¿Quieres sobrescribirlos?`,
100
+ default: false,
101
+ },
102
+ ]);
103
+ return overwrite;
49
104
  }
50
105
 
51
106
  program
@@ -53,74 +108,145 @@ program
53
108
  .description("CLI para instalar componentes de react-native-varia")
54
109
  .version("1.0.0");
55
110
 
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
-
79
111
  program
80
- .command('setup')
81
- .description('Copia la carpeta varia a src/styles/varia')
112
+ .command("setup")
113
+ .description("Copia la carpeta varia y patterns al proyecto (src/style/varia y src/patterns)")
82
114
  .action(() => {
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
115
+ const variaSrc = path.join(__dirname, "../lib/varia");
116
+ const variaDest = path.join(process.cwd(), "src/style/varia");
117
+
118
+ const patternsSrc = path.join(__dirname, "../lib/patterns");
119
+ const patternsDest = path.join(process.cwd(), "src/patterns");
86
120
 
87
121
  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}`);
122
+ // Copiar varia
123
+ fs.ensureDirSync(path.dirname(variaDest));
124
+ fs.copySync(variaSrc, variaDest, { overwrite: true });
125
+ console.log(`✅ Carpeta "varia" copiada a ${variaDest}`);
126
+
127
+ // Copiar patterns
128
+ fs.ensureDirSync(path.dirname(patternsDest));
129
+ fs.copySync(patternsSrc, patternsDest, { overwrite: true });
130
+ console.log(`✅ Carpeta "patterns" copiada a ${patternsDest}`);
91
131
  } catch (err) {
92
- console.error(`❌ Error al copiar la carpeta "varia": ${err.message}`);
132
+ console.error(`❌ Error durante el setup: ${err.message}`);
93
133
  }
94
134
  });
95
135
 
96
- program
97
- .command('add-patterns')
98
- .description('Copia la carpeta lib/patterns a src/patterns')
136
+
137
+ program
138
+ .command("add-patterns")
139
+ .description("Copia la carpeta lib/patterns a src/patterns")
99
140
  .action(() => {
100
- const sourceDir = path.join(__dirname, '../lib/patterns');
101
- const destDir = path.join(process.cwd(), 'src/patterns');
141
+ const sourceDir = path.join(__dirname, "../lib/patterns");
142
+ const destDir = path.join(process.cwd(), "src/patterns");
102
143
 
103
144
  try {
104
- fs.ensureDirSync(destDir); // Asegura que el directorio de destino exista
145
+ fs.ensureDirSync(destDir);
105
146
  fs.copySync(sourceDir, destDir, { overwrite: true });
106
- console.log('✅ Carpeta patterns copiada a src/patterns');
147
+ console.log("✅ Carpeta patterns copiada a src/patterns");
107
148
  } catch (err) {
108
149
  console.error(`❌ Error al copiar patterns: ${err.message}`);
109
150
  }
110
151
  });
111
152
 
153
+ // program
154
+ // .command("add <components...>")
155
+ // .description("Copia uno o más componentes y sus recipes desde la librería a tu proyecto")
156
+ // .option("-d, --dest <path>", "Ruta de destino de componentes", "src/components")
157
+ // .option("-t, --theme <path>", "Ruta de destino de recipes", "src/theme")
158
+ // .action(async (components, options) => {
159
+ // const available = getAvailableComponents();
160
+ // const componentsCapitalized = components.map(
161
+ // (c) => c.charAt(0).toUpperCase() + c.slice(1)
162
+ // );
163
+
164
+ // // 🔹 Obtener dependencias totales
165
+ // const allComponents = new Set();
166
+ // const componentToDeps = {}; // para saber qué depende de qué
167
+ // for (const c of componentsCapitalized) {
168
+ // const deps = resolveDependencies(c);
169
+ // componentToDeps[c] = deps;
170
+ // allComponents.add(c);
171
+ // deps.forEach((d) => allComponents.add(d));
172
+ // }
173
+
174
+ // const allComponentsArray = Array.from(allComponents);
175
+
176
+ // // 🔹 Validar existencia
177
+ // const notFound = allComponentsArray.filter((c) => !available.includes(c));
178
+ // if (notFound.length > 0) {
179
+ // console.error(`❌ Los siguientes componentes no existen: ${notFound.join(", ")}`);
180
+ // console.log("\n📦 Componentes disponibles:");
181
+ // available.forEach((name) => console.log(` - ${name}`));
182
+ // process.exit(1);
183
+ // }
184
+
185
+ // // 🔹 Preparar instalación
186
+ // for (const mainComponent of componentsCapitalized) {
187
+ // const componentPath = path.join(process.cwd(), options.dest, `${mainComponent}.tsx`);
188
+ // let overwriteMain = true;
189
+
190
+ // // Preguntar solo si el componente principal existe
191
+ // if (fs.existsSync(componentPath)) {
192
+ // const { overwrite } = await inquirer.prompt([
193
+ // {
194
+ // type: "confirm",
195
+ // name: "overwrite",
196
+ // message: `El componente "${mainComponent}" ya existe. ¿Deseas sobrescribirlo?`,
197
+ // default: false,
198
+ // },
199
+ // ]);
200
+
201
+ // overwriteMain = overwrite;
202
+ // if (!overwriteMain) {
203
+ // console.log(`⏭️ Componente "${mainComponent}" no sobrescrito.`);
204
+ // }
205
+ // }
206
+
207
+ // // 🔹 Copiar componente principal
208
+ // copyComponentAndRecipe(mainComponent, options.dest, options.theme, overwriteMain);
209
+
210
+ // // 🔹 Copiar dependencias (sin sobrescribir si existen)
211
+ // const deps = componentToDeps[mainComponent] || [];
212
+ // for (const dep of deps) {
213
+ // const depPath = path.join(process.cwd(), options.dest, `${dep}.tsx`);
214
+ // const exists = fs.existsSync(depPath);
215
+ // if (exists) {
216
+ // console.log(`⏭️ Dependencia "${dep}" ya existe. No se sobrescribe.`);
217
+ // continue;
218
+ // }
219
+ // copyComponentAndRecipe(dep, options.dest, options.theme, true);
220
+ // }
221
+ // }
222
+ // });
223
+
112
224
  program
113
225
  .command("add <components...>")
114
226
  .description("Copia uno o más componentes y sus recipes desde la librería a tu proyecto")
115
227
  .option("-d, --dest <path>", "Ruta de destino de componentes", "src/components")
116
228
  .option("-t, --theme <path>", "Ruta de destino de recipes", "src/theme")
117
- .action((components, options) => {
229
+ .option("-i, --icons <path>", "Ruta de destino de íconos", "src/icons")
230
+ .action(async (components, options) => {
118
231
  const available = getAvailableComponents();
119
232
  const componentsCapitalized = components.map(
120
233
  (c) => c.charAt(0).toUpperCase() + c.slice(1)
121
234
  );
122
235
 
123
- const notFound = componentsCapitalized.filter((c) => !available.includes(c));
236
+ // 🔹 Obtener dependencias totales
237
+ const allComponents = new Set();
238
+ const componentToDeps = {}; // para saber qué depende de qué
239
+ for (const c of componentsCapitalized) {
240
+ const deps = resolveDependencies(c);
241
+ componentToDeps[c] = deps;
242
+ allComponents.add(c);
243
+ deps.forEach((d) => allComponents.add(d));
244
+ }
245
+
246
+ const allComponentsArray = Array.from(allComponents);
247
+
248
+ // 🔹 Validar existencia
249
+ const notFound = allComponentsArray.filter((c) => !available.includes(c));
124
250
  if (notFound.length > 0) {
125
251
  console.error(`❌ Los siguientes componentes no existen: ${notFound.join(", ")}`);
126
252
  console.log("\n📦 Componentes disponibles:");
@@ -128,90 +254,151 @@ program
128
254
  process.exit(1);
129
255
  }
130
256
 
131
- componentsCapitalized.forEach((component) => {
132
- copyComponentAndRecipe(component, options.dest, options.theme);
133
- });
134
- });
257
+ // 🔹 Preparar instalación
258
+ for (const mainComponent of componentsCapitalized) {
259
+ const componentPath = path.join(process.cwd(), options.dest, `${mainComponent}.tsx`);
260
+ let overwriteMain = true;
135
261
 
136
-
137
- function copyIconTemplate(iconName, dest) {
138
- const srcPath = path.join(COMPONENTS_DIR, "Icon.tsx"); // plantilla
139
- const destPath = path.join(process.cwd(), dest, `${iconName}.tsx`); // nombre final
140
-
141
- if (!fs.existsSync(srcPath)) {
142
- console.error(`❌ Plantilla de icono no encontrada en: ${srcPath}`);
143
- return false;
144
- }
145
-
146
- try {
147
- // Leemos el contenido de la plantilla
148
- let content = fs.readFileSync(srcPath, "utf-8");
149
-
150
- // Reemplazamos el nombre del componente (IconName → el nombre deseado)
151
- content = content.replace(/\bIconName\b/g, iconName);
152
-
153
- fs.ensureDirSync(path.dirname(destPath)); // crear carpeta si no existe
154
- fs.writeFileSync(destPath, content);
155
-
156
- console.log(`✅ Icono "${iconName}" copiado a: ${destPath}`);
157
- return true;
158
- } catch (err) {
159
- console.error(`❌ No se pudo copiar el icono "${iconName}": ${err.message}`);
160
- return false;
262
+ // Preguntar solo si el componente principal existe
263
+ if (fs.existsSync(componentPath)) {
264
+ const { overwrite } = await inquirer.prompt([
265
+ {
266
+ type: "confirm",
267
+ name: "overwrite",
268
+ message: `El componente "${mainComponent}" ya existe. ¿Deseas sobrescribirlo?`,
269
+ default: false,
270
+ },
271
+ ]);
272
+
273
+ overwriteMain = overwrite;
274
+ if (!overwriteMain) {
275
+ console.log(`⏭️ Componente "${mainComponent}" no sobrescrito.`);
276
+ }
277
+ }
278
+
279
+ // 🔹 Copiar componente principal
280
+ copyComponentAndRecipe(mainComponent, options.dest, options.theme, overwriteMain);
281
+
282
+ // 🔹 Copiar dependencias (sin sobrescribir si existen)
283
+ const deps = componentToDeps[mainComponent] || [];
284
+ for (const dep of deps) {
285
+ const depPath = path.join(process.cwd(), options.dest, `${dep}.tsx`);
286
+ const exists = fs.existsSync(depPath);
287
+ if (exists) {
288
+ console.log(`⏭️ Dependencia "${dep}" ya existe. No se sobrescribe.`);
289
+ continue;
290
+ }
291
+ copyComponentAndRecipe(dep, options.dest, options.theme, true);
292
+ }
293
+
294
+ // 🔹 Copiar íconos dependientes
295
+ const iconDeps = ICON_DEPENDENCIES[mainComponent] || [];
296
+ if (iconDeps.length > 0) {
297
+ console.log(`🎨 Añadiendo íconos requeridos por "${mainComponent}": ${iconDeps.join(", ")}`);
298
+
299
+ for (const iconName of iconDeps) {
300
+ const destIconPath = path.join(process.cwd(), options.icons, `${iconName}.tsx`);
301
+ if (fs.existsSync(destIconPath)) {
302
+ console.log(`⏭️ Icono "${iconName}" ya existe. No se sobrescribe.`);
303
+ continue;
304
+ }
305
+ copyIconTemplate(iconName, options.icons);
306
+ }
307
+
308
+ // Asegurar que IconWrapper esté disponible
309
+ ensureIconWrapper(options.dest, options.theme);
310
+ }
161
311
  }
312
+ });
313
+
314
+
315
+ function copyIconTemplate(iconName, dest) {
316
+ const srcPath = path.join(COMPONENTS_DIR, "Icon.tsx");
317
+ const destPath = path.join(process.cwd(), dest, `${iconName}.tsx`);
318
+
319
+ if (!fs.existsSync(srcPath)) {
320
+ console.error(`❌ Plantilla de icono no encontrada en: ${srcPath}`);
321
+ return false;
162
322
  }
163
-
164
- /**
165
- * Copia IconWrapper si no existe en la app
166
- */
167
- function ensureIconWrapper(destComponents, destTheme) {
168
- const wrapperComponentDest = path.join(process.cwd(), destComponents, "IconWrapper.tsx");
169
- const wrapperRecipeDest = path.join(process.cwd(), destTheme, "IconWrapper.recipe.tsx");
170
-
171
- if (fs.existsSync(wrapperComponentDest)) {
172
- return; // ya existe
173
- }
174
-
175
- const wrapperComponentSrc = path.join(COMPONENTS_DIR, "IconWrapper.tsx");
176
- const wrapperRecipeSrc = path.join(THEME_DIR, "IconWrapper.recipe.tsx");
177
-
178
- // Copiar componente y recipe
179
- if (fs.existsSync(wrapperComponentSrc)) {
180
- fs.ensureDirSync(path.dirname(wrapperComponentDest));
181
- fs.copySync(wrapperComponentSrc, wrapperComponentDest, { overwrite: true, errorOnExist: false });
182
- console.log(`✅ IconWrapper copiado a: ${wrapperComponentDest}`);
183
- }
184
-
185
- if (fs.existsSync(wrapperRecipeSrc)) {
186
- fs.ensureDirSync(path.dirname(wrapperRecipeDest));
187
- fs.copySync(wrapperRecipeSrc, wrapperRecipeDest, { overwrite: true, errorOnExist: false });
188
- console.log(`✅ IconWrapper recipe copiado a: ${wrapperRecipeDest}`);
189
- }
323
+
324
+ try {
325
+ let content = fs.readFileSync(srcPath, "utf-8");
326
+ content = content.replace(/\bIconName\b/g, iconName);
327
+
328
+ fs.ensureDirSync(path.dirname(destPath));
329
+ fs.writeFileSync(destPath, content);
330
+
331
+ console.log(`✅ Icono "${iconName}" copiado a: ${destPath}`);
332
+ return true;
333
+ } catch (err) {
334
+ console.error(`❌ No se pudo copiar el icono "${iconName}": ${err.message}`);
335
+ return false;
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Copia IconWrapper si no existe en la app
341
+ */
342
+ function ensureIconWrapper(destComponents, destTheme) {
343
+ const wrapperComponentDest = path.join(process.cwd(), destComponents, "IconWrapper.tsx");
344
+ const wrapperRecipeDest = path.join(process.cwd(), destTheme, "IconWrapper.recipe.tsx");
345
+
346
+ if (fs.existsSync(wrapperComponentDest)) {
347
+ return;
348
+ }
349
+
350
+ const wrapperComponentSrc = path.join(COMPONENTS_DIR, "IconWrapper.tsx");
351
+ const wrapperRecipeSrc = path.join(THEME_DIR, "IconWrapper.recipe.tsx");
352
+
353
+ if (fs.existsSync(wrapperComponentSrc)) {
354
+ fs.ensureDirSync(path.dirname(wrapperComponentDest));
355
+ fs.copySync(wrapperComponentSrc, wrapperComponentDest, { overwrite: true });
356
+ console.log(`✅ IconWrapper copiado a: ${wrapperComponentDest}`);
357
+ }
358
+
359
+ if (fs.existsSync(wrapperRecipeSrc)) {
360
+ fs.ensureDirSync(path.dirname(wrapperRecipeDest));
361
+ fs.copySync(wrapperRecipeSrc, wrapperRecipeDest, { overwrite: true });
362
+ console.log(`✅ IconWrapper recipe copiado a: ${wrapperRecipeDest}`);
190
363
  }
191
-
192
- // Comando CLI
193
- program
194
- .command("add-icon [iconName]")
195
- .description("Copia un icono basado en la plantilla Icon.tsx")
196
- .option("-n, --name <iconName>", "Nombre del icono")
197
- .option("-d, --dest <path>", "Ruta de destino de iconos", "src/icons")
198
- .option("-c, --components <path>", "Ruta de destino de componentes", "src/components")
199
- .option("-t, --theme <path>", "Ruta de destino de recipes", "src/theme")
200
- .action((iconNameArg, options) => {
201
- const rawName = iconNameArg || options.name;
202
- if (!rawName) {
203
- console.error("❌ Debes indicar el nombre del icono como argumento o con --name");
204
- process.exit(1);
364
+ }
365
+
366
+ // Comando CLI: add-icon
367
+ program
368
+ .command("add-icon [iconName]")
369
+ .description("Copia un icono basado en la plantilla Icon.tsx")
370
+ .option("-n, --name <iconName>", "Nombre del icono")
371
+ .option("-d, --dest <path>", "Ruta de destino de iconos", "src/icons")
372
+ .option("-c, --components <path>", "Ruta de destino de componentes", "src/components")
373
+ .option("-t, --theme <path>", "Ruta de destino de recipes", "src/theme")
374
+ .action(async (iconNameArg, options) => {
375
+ const rawName = iconNameArg || options.name;
376
+ if (!rawName) {
377
+ console.error("❌ Debes indicar el nombre del icono como argumento o con --name");
378
+ process.exit(1);
379
+ }
380
+
381
+ const finalName = rawName.charAt(0).toUpperCase() + rawName.slice(1);
382
+ const destPath = path.join(process.cwd(), options.dest, `${finalName}.tsx`);
383
+
384
+ // 🔹 Si ya existe, preguntar antes de sobrescribir
385
+ if (fs.existsSync(destPath)) {
386
+ const { overwrite } = await inquirer.prompt([
387
+ {
388
+ type: "confirm",
389
+ name: "overwrite",
390
+ message: `El icono "${finalName}" ya existe. ¿Quieres sobrescribirlo?`,
391
+ default: false,
392
+ },
393
+ ]);
394
+ if (!overwrite) {
395
+ console.log("⏭️ Icono no sobrescrito.");
396
+ return;
205
397
  }
206
-
207
- // Capitalizamos primera letra
208
- const finalName = rawName.charAt(0).toUpperCase() + rawName.slice(1);
209
-
210
- copyIconTemplate(finalName, options.dest);
211
-
212
- // Aseguramos IconWrapper
213
- ensureIconWrapper(options.components, options.theme);
214
- });
215
-
216
-
217
- program.parse(process.argv);
398
+ }
399
+
400
+ copyIconTemplate(finalName, options.dest);
401
+ ensureIconWrapper(options.components, options.theme);
402
+ });
403
+
404
+ program.parse(process.argv);
@@ -40,22 +40,14 @@ const Badge = ({
40
40
 
41
41
  const displayedContent = max && content > max ? `${max}+` : content
42
42
 
43
- // @ts-ignore
44
- const badgeSize = BadgeStyles.container(colorPalette).minWidth
45
- const withoutChildrenSize = !children ? badgeSize : 'auto'
46
-
47
- return (
48
- <HStack
49
- style={{
50
- position: 'relative',
51
- minWidth: withoutChildrenSize,
52
- height: withoutChildrenSize,
53
- }}>
54
- {children && children}
43
+ return children ? (
44
+ <HStack style={{position: 'relative'}}>
45
+ {children}
55
46
  <View
56
47
  testID="varia-badge"
57
48
  style={[
58
- styles.badge(x, y),
49
+ styles.badge,
50
+ styles.badgeAbsolute(x, y),
59
51
  BadgeStyles.container(colorPalette),
60
52
  mixins && mixins,
61
53
  ]}>
@@ -64,18 +56,23 @@ const Badge = ({
64
56
  </Text>
65
57
  </View>
66
58
  </HStack>
59
+ ) : (
60
+ <View
61
+ testID="varia-badge"
62
+ style={[
63
+ styles.badge,
64
+ BadgeStyles.container(colorPalette),
65
+ mixins && mixins,
66
+ ]}>
67
+ <Text style={[styles.text, BadgeStyles.text(colorPalette)]}>
68
+ {displayedContent}
69
+ </Text>
70
+ </View>
67
71
  )
68
72
  }
69
73
 
70
74
  const styles = StyleSheet.create({
71
- badge: (x, y) => ({
72
- position: 'absolute',
73
- [y]: 0,
74
- [x]: 0,
75
- transform: [
76
- {translateY: y === 'top' ? '-30%' : '30%'},
77
- {translateX: x === 'left' ? '-30%' : '30%'},
78
- ],
75
+ badge: {
79
76
  paddingVertical: 1,
80
77
  paddingHorizontal: 6,
81
78
  zIndex: 1,
@@ -83,6 +80,15 @@ const styles = StyleSheet.create({
83
80
  borderWidth: 1,
84
81
  alignItems: 'center',
85
82
  justifyContent: 'center',
83
+ },
84
+ badgeAbsolute: (x, y) => ({
85
+ position: 'absolute',
86
+ [y]: 0,
87
+ [x]: 0,
88
+ transform: [
89
+ {translateY: y === 'top' ? '-50%' : '50%'},
90
+ {translateX: x === 'left' ? '-50%' : '50%'},
91
+ ],
86
92
  }),
87
93
  text: {
88
94
  textAlign: 'center',
@@ -3,7 +3,7 @@ import {StyleSheet, UnistylesVariants} from 'react-native-unistyles'
3
3
  import {ButtonStyles, ButtonDefaultVariants} from '../theme/Button.recipe'
4
4
  import {useMemo} from 'react'
5
5
  import {IconWrapperProps} from './IconWrapper'
6
- import Spinner from './Spinner'
6
+ import Spinner, {SpinnerProps} from './Spinner'
7
7
  import {PalettesWithNestedKeys} from '../style/varia/types'
8
8
 
9
9
  type TextAdjustment = 'singleLine' | 'multiline' | 'adjustToFit'
@@ -12,7 +12,7 @@ type ButtonVariants = UnistylesVariants<typeof ButtonStyles>
12
12
 
13
13
  type ButtonProps = ButtonVariants & {
14
14
  colorPalette?: PalettesWithNestedKeys
15
- text: string
15
+ text?: string
16
16
  onPress: () => void
17
17
  loading?: boolean
18
18
  disabled?: boolean
@@ -21,7 +21,7 @@ type ButtonProps = ButtonVariants & {
21
21
  textAdjustment?: TextAdjustment
22
22
  icon?: {
23
23
  component: React.ComponentType<IconWrapperProps>
24
- position: 'left' | 'right'
24
+ position?: 'left' | 'right'
25
25
  scale?: number
26
26
  rotation?: number
27
27
  size?: number
@@ -75,7 +75,6 @@ const Button = ({
75
75
  rotation: icon.rotation,
76
76
  scale: icon.scale,
77
77
  colorPalette,
78
- //@ts-ignore
79
78
  size: icon.size,
80
79
  color: ButtonStyles.text(colorPalette).color,
81
80
  }}
@@ -93,19 +92,19 @@ const Button = ({
93
92
  disabled={disabled || loading}>
94
93
  {loading ? (
95
94
  <Spinner
96
- //@ts-ignore
97
- size={ButtonStyles.text.fontSize}
98
- //@ts-ignore
99
- color={ButtonStyles.text.color}
95
+ size={size as SpinnerProps['size']}
96
+ color={ButtonStyles.text(colorPalette).color}
100
97
  />
101
98
  ) : (
102
99
  <>
103
100
  {icon?.position === 'left' && IconRendered}
104
- <Text
105
- {...getTextProps()}
106
- style={[styles.text, ButtonStyles.text(colorPalette)]}>
107
- {text}
108
- </Text>
101
+ {text && (
102
+ <Text
103
+ {...getTextProps()}
104
+ style={[styles.text, ButtonStyles.text(colorPalette)]}>
105
+ {text}
106
+ </Text>
107
+ )}
109
108
  {icon?.position === 'right' && IconRendered}
110
109
  </>
111
110
  )}