@acvl/mobile-components 0.0.0-stage → 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 (297) hide show
  1. package/README.md +146 -2
  2. package/assets/fonts/Inter_400Regular.ttf +0 -0
  3. package/assets/fonts/Inter_500Medium.ttf +0 -0
  4. package/assets/fonts/Inter_600SemiBold.ttf +0 -0
  5. package/assets/fonts/Inter_700Bold.ttf +0 -0
  6. package/assets/fonts/Inter_800ExtraBold.ttf +0 -0
  7. package/assets/fonts/Inter_900Black.ttf +0 -0
  8. package/assets/fonts/OFL.txt +93 -0
  9. package/lib/module/componentes/AccionesDelEncabezado.js +212 -0
  10. package/lib/module/componentes/AccionesDelEncabezado.js.map +1 -0
  11. package/lib/module/componentes/BotonDeAvatar.js +55 -0
  12. package/lib/module/componentes/BotonDeAvatar.js.map +1 -0
  13. package/lib/module/componentes/BotonGrande.js +105 -0
  14. package/lib/module/componentes/BotonGrande.js.map +1 -0
  15. package/lib/module/componentes/CabeceraEmpujada.js +101 -0
  16. package/lib/module/componentes/CabeceraEmpujada.js.map +1 -0
  17. package/lib/module/componentes/Chip.js +77 -0
  18. package/lib/module/componentes/Chip.js.map +1 -0
  19. package/lib/module/componentes/ContenidoDePantalla.js +56 -0
  20. package/lib/module/componentes/ContenidoDePantalla.js.map +1 -0
  21. package/lib/module/componentes/EstadoVacio.js +65 -0
  22. package/lib/module/componentes/EstadoVacio.js.map +1 -0
  23. package/lib/module/componentes/Foto.js +106 -0
  24. package/lib/module/componentes/Foto.js.map +1 -0
  25. package/lib/module/componentes/IconoDeRenglon.js +44 -0
  26. package/lib/module/componentes/IconoDeRenglon.js.map +1 -0
  27. package/lib/module/componentes/Logo.js +44 -0
  28. package/lib/module/componentes/Logo.js.map +1 -0
  29. package/lib/module/componentes/Nota.js +51 -0
  30. package/lib/module/componentes/Nota.js.map +1 -0
  31. package/lib/module/componentes/OpcionesExcluyentes.js +69 -0
  32. package/lib/module/componentes/OpcionesExcluyentes.js.map +1 -0
  33. package/lib/module/componentes/PantallaDeError.js +84 -0
  34. package/lib/module/componentes/PantallaDeError.js.map +1 -0
  35. package/lib/module/componentes/Pestanas.js +87 -0
  36. package/lib/module/componentes/Pestanas.js.map +1 -0
  37. package/lib/module/componentes/Rotulo.js +28 -0
  38. package/lib/module/componentes/Rotulo.js.map +1 -0
  39. package/lib/module/componentes/RotuloDeSeccion.js +87 -0
  40. package/lib/module/componentes/RotuloDeSeccion.js.map +1 -0
  41. package/lib/module/componentes/Tarjeta.js +47 -0
  42. package/lib/module/componentes/Tarjeta.js.map +1 -0
  43. package/lib/module/componentes/TarjetaDeDatos.js +79 -0
  44. package/lib/module/componentes/TarjetaDeDatos.js.map +1 -0
  45. package/lib/module/componentes/TiraDeFotos.js +184 -0
  46. package/lib/module/componentes/TiraDeFotos.js.map +1 -0
  47. package/lib/module/componentes/VisorDeFoto.js +171 -0
  48. package/lib/module/componentes/VisorDeFoto.js.map +1 -0
  49. package/lib/module/componentes/logos/bola-blanca.png +0 -0
  50. package/lib/module/componentes/logos/bola.png +0 -0
  51. package/lib/module/componentes/logos/logo-blanco.png +0 -0
  52. package/lib/module/componentes/logos/logo.png +0 -0
  53. package/lib/module/dialogos/HostDeDialogos.js +170 -0
  54. package/lib/module/dialogos/HostDeDialogos.js.map +1 -0
  55. package/lib/module/dialogos/dialogos.js +112 -0
  56. package/lib/module/dialogos/dialogos.js.map +1 -0
  57. package/lib/module/formularios/CampoDeSeleccion.js +47 -0
  58. package/lib/module/formularios/CampoDeSeleccion.js.map +1 -0
  59. package/lib/module/formularios/SelectorDeOpcion.js +406 -0
  60. package/lib/module/formularios/SelectorDeOpcion.js.map +1 -0
  61. package/lib/module/formularios/TextoDeAccesoControlado.js +73 -0
  62. package/lib/module/formularios/TextoDeAccesoControlado.js.map +1 -0
  63. package/lib/module/formularios/campos.js +493 -0
  64. package/lib/module/formularios/campos.js.map +1 -0
  65. package/lib/module/formularios/controlados.js +197 -0
  66. package/lib/module/formularios/controlados.js.map +1 -0
  67. package/lib/module/formularios/errores.js +91 -0
  68. package/lib/module/formularios/errores.js.map +1 -0
  69. package/lib/module/formularios/guardado.js +78 -0
  70. package/lib/module/formularios/guardado.js.map +1 -0
  71. package/lib/module/formularios/useBusqueda.js +22 -0
  72. package/lib/module/formularios/useBusqueda.js.map +1 -0
  73. package/lib/module/fotos/elegir.js +178 -0
  74. package/lib/module/fotos/elegir.js.map +1 -0
  75. package/lib/module/fotos/index.js +8 -0
  76. package/lib/module/fotos/index.js.map +1 -0
  77. package/lib/module/fotos/reducir.js +93 -0
  78. package/lib/module/fotos/reducir.js.map +1 -0
  79. package/lib/module/hoja/HojaInferior.js +108 -0
  80. package/lib/module/hoja/HojaInferior.js.map +1 -0
  81. package/lib/module/hoja/index.js +7 -0
  82. package/lib/module/hoja/index.js.map +1 -0
  83. package/lib/module/hoja/useMasDeLaFicha.js +48 -0
  84. package/lib/module/hoja/useMasDeLaFicha.js.map +1 -0
  85. package/lib/module/index.js +66 -0
  86. package/lib/module/index.js.map +1 -0
  87. package/lib/module/listas/HojaDeFiltros.js +260 -0
  88. package/lib/module/listas/HojaDeFiltros.js.map +1 -0
  89. package/lib/module/listas/ListaPaginada.js +103 -0
  90. package/lib/module/listas/ListaPaginada.js.map +1 -0
  91. package/lib/module/listas/TarjetaDeslizable.js +118 -0
  92. package/lib/module/listas/TarjetaDeslizable.js.map +1 -0
  93. package/lib/module/listas/paginado.js +11 -0
  94. package/lib/module/listas/paginado.js.map +1 -0
  95. package/lib/module/listas/piezas.js +603 -0
  96. package/lib/module/listas/piezas.js.map +1 -0
  97. package/lib/module/navegacion/BarraDePestanas.js +162 -0
  98. package/lib/module/navegacion/BarraDePestanas.js.map +1 -0
  99. package/lib/module/navegacion/BotonDeBarra.js +58 -0
  100. package/lib/module/navegacion/BotonDeBarra.js.map +1 -0
  101. package/lib/module/navegacion/encabezado.js +103 -0
  102. package/lib/module/navegacion/encabezado.js.map +1 -0
  103. package/lib/module/pantallas/PantallaDeAcceso.js +195 -0
  104. package/lib/module/pantallas/PantallaDeAcceso.js.map +1 -0
  105. package/lib/module/pantallas/PantallaDeEdicion.js +121 -0
  106. package/lib/module/pantallas/PantallaDeEdicion.js.map +1 -0
  107. package/lib/module/pantallas/PantallaDeFicha.js +94 -0
  108. package/lib/module/pantallas/PantallaDeFicha.js.map +1 -0
  109. package/lib/module/pantallas/PantallaDePerfil.js +137 -0
  110. package/lib/module/pantallas/PantallaDePerfil.js.map +1 -0
  111. package/lib/module/tema/ProveedorDeTema.js +122 -0
  112. package/lib/module/tema/ProveedorDeTema.js.map +1 -0
  113. package/lib/module/tema/estilos.js +54 -0
  114. package/lib/module/tema/estilos.js.map +1 -0
  115. package/lib/module/tema/fuentes.js +28 -0
  116. package/lib/module/tema/fuentes.js.map +1 -0
  117. package/lib/module/tema/index.js +8 -0
  118. package/lib/module/tema/index.js.map +1 -0
  119. package/lib/module/tema/paleta.js +107 -0
  120. package/lib/module/tema/paleta.js.map +1 -0
  121. package/lib/module/tema/tipografia.js +32 -0
  122. package/lib/module/tema/tipografia.js.map +1 -0
  123. package/lib/module/texto.js +48 -0
  124. package/lib/module/texto.js.map +1 -0
  125. package/lib/typescript/src/componentes/AccionesDelEncabezado.d.ts +34 -0
  126. package/lib/typescript/src/componentes/AccionesDelEncabezado.d.ts.map +1 -0
  127. package/lib/typescript/src/componentes/BotonDeAvatar.d.ts +17 -0
  128. package/lib/typescript/src/componentes/BotonDeAvatar.d.ts.map +1 -0
  129. package/lib/typescript/src/componentes/BotonGrande.d.ts +26 -0
  130. package/lib/typescript/src/componentes/BotonGrande.d.ts.map +1 -0
  131. package/lib/typescript/src/componentes/CabeceraEmpujada.d.ts +18 -0
  132. package/lib/typescript/src/componentes/CabeceraEmpujada.d.ts.map +1 -0
  133. package/lib/typescript/src/componentes/Chip.d.ts +14 -0
  134. package/lib/typescript/src/componentes/Chip.d.ts.map +1 -0
  135. package/lib/typescript/src/componentes/ContenidoDePantalla.d.ts +17 -0
  136. package/lib/typescript/src/componentes/ContenidoDePantalla.d.ts.map +1 -0
  137. package/lib/typescript/src/componentes/EstadoVacio.d.ts +17 -0
  138. package/lib/typescript/src/componentes/EstadoVacio.d.ts.map +1 -0
  139. package/lib/typescript/src/componentes/Foto.d.ts +41 -0
  140. package/lib/typescript/src/componentes/Foto.d.ts.map +1 -0
  141. package/lib/typescript/src/componentes/IconoDeRenglon.d.ts +25 -0
  142. package/lib/typescript/src/componentes/IconoDeRenglon.d.ts.map +1 -0
  143. package/lib/typescript/src/componentes/Logo.d.ts +13 -0
  144. package/lib/typescript/src/componentes/Logo.d.ts.map +1 -0
  145. package/lib/typescript/src/componentes/Nota.d.ts +7 -0
  146. package/lib/typescript/src/componentes/Nota.d.ts.map +1 -0
  147. package/lib/typescript/src/componentes/OpcionesExcluyentes.d.ts +14 -0
  148. package/lib/typescript/src/componentes/OpcionesExcluyentes.d.ts.map +1 -0
  149. package/lib/typescript/src/componentes/PantallaDeError.d.ts +23 -0
  150. package/lib/typescript/src/componentes/PantallaDeError.d.ts.map +1 -0
  151. package/lib/typescript/src/componentes/Pestanas.d.ts +28 -0
  152. package/lib/typescript/src/componentes/Pestanas.d.ts.map +1 -0
  153. package/lib/typescript/src/componentes/Rotulo.d.ts +6 -0
  154. package/lib/typescript/src/componentes/Rotulo.d.ts.map +1 -0
  155. package/lib/typescript/src/componentes/RotuloDeSeccion.d.ts +20 -0
  156. package/lib/typescript/src/componentes/RotuloDeSeccion.d.ts.map +1 -0
  157. package/lib/typescript/src/componentes/Tarjeta.d.ts +15 -0
  158. package/lib/typescript/src/componentes/Tarjeta.d.ts.map +1 -0
  159. package/lib/typescript/src/componentes/TarjetaDeDatos.d.ts +13 -0
  160. package/lib/typescript/src/componentes/TarjetaDeDatos.d.ts.map +1 -0
  161. package/lib/typescript/src/componentes/TiraDeFotos.d.ts +36 -0
  162. package/lib/typescript/src/componentes/TiraDeFotos.d.ts.map +1 -0
  163. package/lib/typescript/src/componentes/VisorDeFoto.d.ts +23 -0
  164. package/lib/typescript/src/componentes/VisorDeFoto.d.ts.map +1 -0
  165. package/lib/typescript/src/dialogos/HostDeDialogos.d.ts +14 -0
  166. package/lib/typescript/src/dialogos/HostDeDialogos.d.ts.map +1 -0
  167. package/lib/typescript/src/dialogos/dialogos.d.ts +65 -0
  168. package/lib/typescript/src/dialogos/dialogos.d.ts.map +1 -0
  169. package/lib/typescript/src/formularios/CampoDeSeleccion.d.ts +22 -0
  170. package/lib/typescript/src/formularios/CampoDeSeleccion.d.ts.map +1 -0
  171. package/lib/typescript/src/formularios/SelectorDeOpcion.d.ts +59 -0
  172. package/lib/typescript/src/formularios/SelectorDeOpcion.d.ts.map +1 -0
  173. package/lib/typescript/src/formularios/TextoDeAccesoControlado.d.ts +18 -0
  174. package/lib/typescript/src/formularios/TextoDeAccesoControlado.d.ts.map +1 -0
  175. package/lib/typescript/src/formularios/campos.d.ts +107 -0
  176. package/lib/typescript/src/formularios/campos.d.ts.map +1 -0
  177. package/lib/typescript/src/formularios/controlados.d.ts +29 -0
  178. package/lib/typescript/src/formularios/controlados.d.ts.map +1 -0
  179. package/lib/typescript/src/formularios/errores.d.ts +36 -0
  180. package/lib/typescript/src/formularios/errores.d.ts.map +1 -0
  181. package/lib/typescript/src/formularios/guardado.d.ts +36 -0
  182. package/lib/typescript/src/formularios/guardado.d.ts.map +1 -0
  183. package/lib/typescript/src/formularios/useBusqueda.d.ts +7 -0
  184. package/lib/typescript/src/formularios/useBusqueda.d.ts.map +1 -0
  185. package/lib/typescript/src/fotos/elegir.d.ts +58 -0
  186. package/lib/typescript/src/fotos/elegir.d.ts.map +1 -0
  187. package/lib/typescript/src/fotos/index.d.ts +3 -0
  188. package/lib/typescript/src/fotos/index.d.ts.map +1 -0
  189. package/lib/typescript/src/fotos/reducir.d.ts +32 -0
  190. package/lib/typescript/src/fotos/reducir.d.ts.map +1 -0
  191. package/lib/typescript/src/hoja/HojaInferior.d.ts +21 -0
  192. package/lib/typescript/src/hoja/HojaInferior.d.ts.map +1 -0
  193. package/lib/typescript/src/hoja/index.d.ts +3 -0
  194. package/lib/typescript/src/hoja/index.d.ts.map +1 -0
  195. package/lib/typescript/src/hoja/useMasDeLaFicha.d.ts +27 -0
  196. package/lib/typescript/src/hoja/useMasDeLaFicha.d.ts.map +1 -0
  197. package/lib/typescript/src/index.d.ts +45 -0
  198. package/lib/typescript/src/index.d.ts.map +1 -0
  199. package/lib/typescript/src/listas/HojaDeFiltros.d.ts +60 -0
  200. package/lib/typescript/src/listas/HojaDeFiltros.d.ts.map +1 -0
  201. package/lib/typescript/src/listas/ListaPaginada.d.ts +39 -0
  202. package/lib/typescript/src/listas/ListaPaginada.d.ts.map +1 -0
  203. package/lib/typescript/src/listas/TarjetaDeslizable.d.ts +33 -0
  204. package/lib/typescript/src/listas/TarjetaDeslizable.d.ts.map +1 -0
  205. package/lib/typescript/src/listas/paginado.d.ts +16 -0
  206. package/lib/typescript/src/listas/paginado.d.ts.map +1 -0
  207. package/lib/typescript/src/listas/piezas.d.ts +135 -0
  208. package/lib/typescript/src/listas/piezas.d.ts.map +1 -0
  209. package/lib/typescript/src/navegacion/BarraDePestanas.d.ts +57 -0
  210. package/lib/typescript/src/navegacion/BarraDePestanas.d.ts.map +1 -0
  211. package/lib/typescript/src/navegacion/BotonDeBarra.d.ts +15 -0
  212. package/lib/typescript/src/navegacion/BotonDeBarra.d.ts.map +1 -0
  213. package/lib/typescript/src/navegacion/encabezado.d.ts +44 -0
  214. package/lib/typescript/src/navegacion/encabezado.d.ts.map +1 -0
  215. package/lib/typescript/src/pantallas/PantallaDeAcceso.d.ts +32 -0
  216. package/lib/typescript/src/pantallas/PantallaDeAcceso.d.ts.map +1 -0
  217. package/lib/typescript/src/pantallas/PantallaDeEdicion.d.ts +38 -0
  218. package/lib/typescript/src/pantallas/PantallaDeEdicion.d.ts.map +1 -0
  219. package/lib/typescript/src/pantallas/PantallaDeFicha.d.ts +35 -0
  220. package/lib/typescript/src/pantallas/PantallaDeFicha.d.ts.map +1 -0
  221. package/lib/typescript/src/pantallas/PantallaDePerfil.d.ts +19 -0
  222. package/lib/typescript/src/pantallas/PantallaDePerfil.d.ts.map +1 -0
  223. package/lib/typescript/src/tema/ProveedorDeTema.d.ts +32 -0
  224. package/lib/typescript/src/tema/ProveedorDeTema.d.ts.map +1 -0
  225. package/lib/typescript/src/tema/estilos.d.ts +31 -0
  226. package/lib/typescript/src/tema/estilos.d.ts.map +1 -0
  227. package/lib/typescript/src/tema/fuentes.d.ts +20 -0
  228. package/lib/typescript/src/tema/fuentes.d.ts.map +1 -0
  229. package/lib/typescript/src/tema/index.d.ts +6 -0
  230. package/lib/typescript/src/tema/index.d.ts.map +1 -0
  231. package/lib/typescript/src/tema/paleta.d.ts +86 -0
  232. package/lib/typescript/src/tema/paleta.d.ts.map +1 -0
  233. package/lib/typescript/src/tema/tipografia.d.ts +29 -0
  234. package/lib/typescript/src/tema/tipografia.d.ts.map +1 -0
  235. package/lib/typescript/src/texto.d.ts +16 -0
  236. package/lib/typescript/src/texto.d.ts.map +1 -0
  237. package/package.json +135 -5
  238. package/src/componentes/AccionesDelEncabezado.tsx +247 -0
  239. package/src/componentes/BotonDeAvatar.tsx +59 -0
  240. package/src/componentes/BotonGrande.tsx +100 -0
  241. package/src/componentes/CabeceraEmpujada.tsx +69 -0
  242. package/src/componentes/Chip.tsx +60 -0
  243. package/src/componentes/ContenidoDePantalla.tsx +53 -0
  244. package/src/componentes/EstadoVacio.tsx +45 -0
  245. package/src/componentes/Foto.tsx +92 -0
  246. package/src/componentes/IconoDeRenglon.tsx +42 -0
  247. package/src/componentes/Logo.tsx +34 -0
  248. package/src/componentes/Nota.tsx +37 -0
  249. package/src/componentes/OpcionesExcluyentes.tsx +62 -0
  250. package/src/componentes/PantallaDeError.tsx +76 -0
  251. package/src/componentes/Pestanas.tsx +86 -0
  252. package/src/componentes/Rotulo.tsx +21 -0
  253. package/src/componentes/RotuloDeSeccion.tsx +71 -0
  254. package/src/componentes/Tarjeta.tsx +44 -0
  255. package/src/componentes/TarjetaDeDatos.tsx +62 -0
  256. package/src/componentes/TiraDeFotos.tsx +189 -0
  257. package/src/componentes/VisorDeFoto.tsx +181 -0
  258. package/src/componentes/logos/bola-blanca.png +0 -0
  259. package/src/componentes/logos/bola.png +0 -0
  260. package/src/componentes/logos/logo-blanco.png +0 -0
  261. package/src/componentes/logos/logo.png +0 -0
  262. package/src/dialogos/HostDeDialogos.tsx +172 -0
  263. package/src/dialogos/dialogos.ts +148 -0
  264. package/src/formularios/CampoDeSeleccion.tsx +46 -0
  265. package/src/formularios/SelectorDeOpcion.tsx +407 -0
  266. package/src/formularios/TextoDeAccesoControlado.tsx +72 -0
  267. package/src/formularios/campos.tsx +483 -0
  268. package/src/formularios/controlados.tsx +198 -0
  269. package/src/formularios/errores.ts +105 -0
  270. package/src/formularios/guardado.ts +76 -0
  271. package/src/formularios/useBusqueda.ts +19 -0
  272. package/src/fotos/elegir.ts +194 -0
  273. package/src/fotos/index.ts +15 -0
  274. package/src/fotos/reducir.ts +87 -0
  275. package/src/hoja/HojaInferior.tsx +102 -0
  276. package/src/hoja/index.ts +4 -0
  277. package/src/hoja/useMasDeLaFicha.tsx +63 -0
  278. package/src/index.ts +143 -0
  279. package/src/listas/HojaDeFiltros.tsx +261 -0
  280. package/src/listas/ListaPaginada.tsx +117 -0
  281. package/src/listas/TarjetaDeslizable.tsx +126 -0
  282. package/src/listas/paginado.ts +15 -0
  283. package/src/listas/piezas.tsx +594 -0
  284. package/src/navegacion/BarraDePestanas.tsx +198 -0
  285. package/src/navegacion/BotonDeBarra.tsx +61 -0
  286. package/src/navegacion/encabezado.tsx +88 -0
  287. package/src/pantallas/PantallaDeAcceso.tsx +184 -0
  288. package/src/pantallas/PantallaDeEdicion.tsx +116 -0
  289. package/src/pantallas/PantallaDeFicha.tsx +115 -0
  290. package/src/pantallas/PantallaDePerfil.tsx +126 -0
  291. package/src/tema/ProveedorDeTema.tsx +150 -0
  292. package/src/tema/estilos.ts +51 -0
  293. package/src/tema/fuentes.ts +20 -0
  294. package/src/tema/index.ts +10 -0
  295. package/src/tema/paleta.ts +147 -0
  296. package/src/tema/tipografia.ts +29 -0
  297. package/src/texto.tsx +44 -0
@@ -0,0 +1,247 @@
1
+ import { Text } from "../texto";
2
+ import { crearEstilos, renglon, tipografia, usePaleta } from "../tema";
3
+ import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
4
+ import React from "react";
5
+ import {
6
+ ActivityIndicator,
7
+ BackHandler,
8
+ Pressable,
9
+ useWindowDimensions,
10
+ View,
11
+ type LayoutChangeEvent,
12
+ } from "react-native";
13
+ import { Menu } from "react-native-paper";
14
+
15
+ /** Lo que mide un botón y lo que se separan: con eso se cuenta cuántos caben. */
16
+ const LADO = 40;
17
+ const ENTRE = 8;
18
+ /** Los que se ven a lo más, aunque quepan más: más botones ya no se distinguen de un vistazo. */
19
+ const MAXIMO_A_LA_VISTA = 3;
20
+
21
+ export interface AccionDelEncabezado {
22
+ /** El texto del renglón del menú y lo que lee el lector de pantalla. */
23
+ etiqueta: string;
24
+ icono: React.ComponentProps<typeof MaterialCommunityIcons>["name"];
25
+ onPress: () => void;
26
+ disabled?: boolean;
27
+ /** Un indicador en vez del icono, y la acción bloqueada mientras corre. */
28
+ cargando?: boolean;
29
+ /** Para la que borra o cancela: en rojo, en el botón y en el menú. */
30
+ destructiva?: boolean;
31
+ /** Las fijadas son las últimas en irse al menú (Editar). */
32
+ fijada?: boolean;
33
+ /**
34
+ * Una cifra pendiente de la acción: los mensajes sin leer de un hilo. Va sobre su botón o, si
35
+ * la acción se fue al menú, en su renglón — y entonces los tres puntos la suman, porque una
36
+ * cifra escondida no avisa de nada.
37
+ */
38
+ insignia?: number;
39
+ }
40
+
41
+ /**
42
+ * La cifra sobre un botón: «9+» de diez para arriba, que más dígitos no caben en el círculo. Con la
43
+ * letra de la casa (`etiqueta`) y el círculo crece con la del sistema, como el de `RotuloDeSeccion`.
44
+ */
45
+ const Insignia = ({ cuantas }: { cuantas: number }) => {
46
+ const styles = useStyles();
47
+ const { fontScale } = useWindowDimensions();
48
+ const alto = renglon(tipografia.etiqueta).lineHeight * fontScale;
49
+ return (
50
+ <View
51
+ style={[styles.insignia, { minWidth: alto, height: alto, borderRadius: alto / 2 }]}
52
+ pointerEvents="none"
53
+ >
54
+ <Text style={styles.insigniaTexto}>{cuantas > 9 ? "9+" : cuantas}</Text>
55
+ </View>
56
+ );
57
+ };
58
+
59
+ const Boton = ({
60
+ accion,
61
+ onPress,
62
+ }: {
63
+ accion: Pick<
64
+ AccionDelEncabezado,
65
+ "etiqueta" | "icono" | "disabled" | "cargando" | "destructiva" | "insignia"
66
+ >;
67
+ onPress: () => void;
68
+ }) => {
69
+ const c = usePaleta();
70
+ const styles = useStyles();
71
+ return (
72
+ <Pressable
73
+ onPress={onPress}
74
+ disabled={accion.disabled || accion.cargando}
75
+ accessibilityRole="button"
76
+ accessibilityLabel={accion.etiqueta}
77
+ hitSlop={4}
78
+ style={({ pressed }) => [
79
+ styles.boton,
80
+ accion.disabled && styles.apagado,
81
+ pressed && styles.presionado,
82
+ ]}
83
+ >
84
+ {accion.cargando ? (
85
+ <ActivityIndicator size="small" color={c.primary} />
86
+ ) : (
87
+ <MaterialCommunityIcons
88
+ name={accion.icono}
89
+ size={22}
90
+ color={accion.destructiva ? c.primary : c.secondaryDark}
91
+ />
92
+ )}
93
+ {accion.insignia ? <Insignia cuantas={accion.insignia} /> : null}
94
+ </Pressable>
95
+ );
96
+ };
97
+
98
+ /**
99
+ * Las acciones de una ficha en su encabezado: **las que quepan como botones y las demás en el menú
100
+ * de los tres puntos**. Es el `ResponsiveActions` de la app de acv-wms con la paleta de la casa.
101
+ *
102
+ * No mide los botones: mide el hueco que le deja el título (`onLayout`) y cuenta cuántos de
103
+ * `LADO` caben. Si caben todas, van todas; si no, una menos y el menú. Las `fijadas` son las
104
+ * últimas en irse, sin cambiar el orden en que se ven. Quien la pone le da al título
105
+ * `flexShrink: 1` y no `flex: 1`, para que le deje espacio.
106
+ */
107
+ export default function AccionesDelEncabezado({ acciones }: { acciones: AccionDelEncabezado[] }) {
108
+ const c = usePaleta();
109
+ const styles = useStyles();
110
+ const [hueco, setHueco] = React.useState<number | null>(null);
111
+ const [menuAbierto, setMenuAbierto] = React.useState(false);
112
+
113
+ // Atrás con el menú abierto sólo lo cierra: si no, salía de la pantalla con el menú encima.
114
+ React.useEffect(() => {
115
+ if (!menuAbierto) return;
116
+ const sub = BackHandler.addEventListener("hardwareBackPress", () => {
117
+ setMenuAbierto(false);
118
+ return true;
119
+ });
120
+ return () => sub.remove();
121
+ }, [menuAbierto]);
122
+
123
+ const medir = (e: LayoutChangeEvent) => {
124
+ const ancho = e.nativeEvent.layout.width;
125
+ if (ancho === hueco) return;
126
+ setHueco(ancho);
127
+ setMenuAbierto(false);
128
+ };
129
+
130
+ if (!acciones.length) return null;
131
+
132
+ const caben = hueco === null ? 0 : Math.floor((hueco + ENTRE) / (LADO + ENTRE));
133
+ const todas = acciones.length <= Math.min(caben, MAXIMO_A_LA_VISTA);
134
+ const botones = todas ? acciones.length : Math.max(Math.min(caben - 1, MAXIMO_A_LA_VISTA), 0);
135
+ const aLaVista = new Set(
136
+ [...acciones]
137
+ .sort((a, b) => Number(Boolean(b.fijada)) - Number(Boolean(a.fijada)))
138
+ .slice(0, botones),
139
+ );
140
+ const visibles = acciones.filter((a) => aLaVista.has(a));
141
+ const enElMenu = acciones.filter((a) => !aLaVista.has(a));
142
+ const escondidas = enElMenu.reduce((suma, a) => suma + (a.insignia ?? 0), 0);
143
+ const cerrar = () => setMenuAbierto(false);
144
+
145
+ return (
146
+ <View style={styles.barra} onLayout={medir}>
147
+ {hueco !== null ? (
148
+ <>
149
+ {visibles.map((a) => (
150
+ <Boton key={a.etiqueta} accion={a} onPress={a.onPress} />
151
+ ))}
152
+ {enElMenu.length ? (
153
+ <Menu
154
+ visible={menuAbierto}
155
+ onDismiss={cerrar}
156
+ anchorPosition="bottom"
157
+ // Edge-to-edge: sin esto Paper cuenta dos veces la barra de estado.
158
+ statusBarHeight={0}
159
+ contentStyle={styles.menu}
160
+ anchor={
161
+ <Boton
162
+ accion={{
163
+ etiqueta: "Más acciones",
164
+ icono: "dots-vertical",
165
+ insignia: escondidas,
166
+ }}
167
+ onPress={() => setMenuAbierto(true)}
168
+ />
169
+ }
170
+ >
171
+ {enElMenu.map((a) => (
172
+ <Menu.Item
173
+ key={a.etiqueta}
174
+ title={
175
+ <Text
176
+ style={[styles.menuTexto, a.destructiva && styles.rojo]}
177
+ >
178
+ {a.etiqueta}
179
+ {a.insignia ? ` (${a.insignia})` : ""}
180
+ </Text>
181
+ }
182
+ disabled={a.disabled || a.cargando}
183
+ leadingIcon={() =>
184
+ a.cargando ? (
185
+ <ActivityIndicator size="small" color={c.primary} />
186
+ ) : (
187
+ <MaterialCommunityIcons
188
+ name={a.icono}
189
+ size={22}
190
+ color={a.destructiva ? c.primary : c.secondaryDark}
191
+ />
192
+ )
193
+ }
194
+ onPress={() => {
195
+ cerrar();
196
+ a.onPress();
197
+ }}
198
+ />
199
+ ))}
200
+ </Menu>
201
+ ) : null}
202
+ </>
203
+ ) : null}
204
+ </View>
205
+ );
206
+ }
207
+
208
+ const useStyles = crearEstilos((c) => ({
209
+ barra: {
210
+ flexGrow: 1,
211
+ flexBasis: 0,
212
+ minWidth: LADO,
213
+ flexDirection: "row",
214
+ justifyContent: "flex-end",
215
+ gap: ENTRE,
216
+ alignSelf: "center",
217
+ },
218
+ boton: {
219
+ width: LADO,
220
+ height: LADO,
221
+ borderRadius: LADO / 2,
222
+ borderWidth: 1.5,
223
+ borderColor: c.secondaryLighter,
224
+ backgroundColor: c.superficieTenue,
225
+ alignItems: "center",
226
+ justifyContent: "center",
227
+ },
228
+ apagado: { opacity: 0.45 },
229
+ presionado: { opacity: 0.7 },
230
+ menu: { backgroundColor: c.superficie, borderRadius: 12 },
231
+ insignia: {
232
+ position: "absolute",
233
+ // Dentro del círculo y no colgada de su esquina: en Android lo que se sale del padre se
234
+ // recorta, y la cifra quedaba a medias.
235
+ top: 0,
236
+ right: 0,
237
+ paddingHorizontal: 4,
238
+ alignItems: "center",
239
+ justifyContent: "center",
240
+ backgroundColor: c.primary,
241
+ borderWidth: 2,
242
+ borderColor: c.superficie,
243
+ },
244
+ insigniaTexto: { ...renglon(tipografia.etiqueta), fontWeight: "800", color: c.sobrePrimario },
245
+ menuTexto: { fontSize: 17, fontWeight: "600" },
246
+ rojo: { color: c.primary },
247
+ }));
@@ -0,0 +1,59 @@
1
+ import { Pressable, StyleSheet } from "react-native";
2
+ import { Avatar } from "react-native-paper";
3
+ import { tipografia } from "../tema";
4
+
5
+ /**
6
+ * La inicial de cada parte, hasta dos: `inicialesDe(nombre, apellidos)` da «JP»; con sólo el nombre
7
+ * de la cuenta, su primera letra; sin nada, una inicial neutra.
8
+ */
9
+ export const inicialesDe = (...partes: (string | null | undefined)[]): string =>
10
+ (
11
+ partes
12
+ .map((p) => (p ?? "").trim().charAt(0))
13
+ .filter(Boolean)
14
+ .slice(0, 2)
15
+ .join("") || "?"
16
+ ).toUpperCase();
17
+
18
+ /**
19
+ * El avatar de quien entró, en el header de las pestañas: el acceso al perfil (y a cerrar sesión).
20
+ * Quien lo pone decide las iniciales y a dónde lleva.
21
+ */
22
+ const BotonDeAvatar = ({
23
+ iniciales,
24
+ onPress,
25
+ etiqueta = "Perfil",
26
+ }: {
27
+ iniciales: string;
28
+ onPress: () => void;
29
+ /** Lo que lee el lector de pantalla. */
30
+ etiqueta?: string;
31
+ }) => (
32
+ <Pressable
33
+ onPress={onPress}
34
+ hitSlop={8}
35
+ accessibilityRole="button"
36
+ accessibilityLabel={etiqueta}
37
+ style={({ pressed }) => [styles.btn, pressed && { opacity: 0.6 }]}
38
+ >
39
+ <Avatar.Text
40
+ size={36}
41
+ label={iniciales.slice(0, 2).toUpperCase()}
42
+ // Blanca sobre el rojo en los dos modos: el tema oscuro de Paper la ponía oscura.
43
+ color="#ffffff"
44
+ labelStyle={styles.initial}
45
+ />
46
+ </Pressable>
47
+ );
48
+
49
+ const styles = StyleSheet.create({
50
+ btn: {
51
+ width: 40,
52
+ height: 40,
53
+ alignItems: "center",
54
+ justifyContent: "center",
55
+ },
56
+ initial: { fontSize: tipografia.etiqueta, fontWeight: "700", lineHeight: 20 },
57
+ });
58
+
59
+ export default BotonDeAvatar;
@@ -0,0 +1,100 @@
1
+ import { crearEstilos, renglon, tipografia, usePaleta } from "../tema";
2
+ import IconoDeRenglon from "../componentes/IconoDeRenglon";
3
+ import { Text } from "../texto";
4
+ import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
5
+ import React from "react";
6
+ import { ActivityIndicator, Pressable, View } from "react-native";
7
+
8
+ interface Props {
9
+ children: string;
10
+ icono?: React.ComponentProps<typeof MaterialCommunityIcons>["name"];
11
+ onPress: () => void;
12
+ disabled?: boolean;
13
+ cargando?: boolean;
14
+ /**
15
+ * `relleno` para la acción principal; `contorno` para las de apoyo; `destructivo` para la que
16
+ * borra o deshace algo (Deshacer, Descartar, Cerrar sesión), en rojo oscuro; `listo` para algo
17
+ * ya cumplido que todavía se puede abrir (la evidencia completa), en verde.
18
+ */
19
+ modo?: "relleno" | "contorno" | "destructivo" | "listo";
20
+ }
21
+
22
+ /**
23
+ * El botón de una acción del flujo (Iniciar, Completar, Reintentar): ancho completo, alto
24
+ * generoso y letra de subtítulo, para atinarle de pie y con la letra del teléfono al 180%.
25
+ *
26
+ * Es propio y no el `Button` de Paper porque ése corta su texto a un renglón: con la letra grande
27
+ * «Iniciar asignación desde donde estás» quedaba en «Iniciar asignac…». Aquí el texto parte en los
28
+ * renglones que haga falta y el botón crece con él.
29
+ */
30
+ const BotonGrande = ({ children, icono, onPress, disabled, cargando, modo = "relleno" }: Props) => {
31
+ const c = usePaleta();
32
+ const styles = useStyles();
33
+ const inactivo = disabled || cargando;
34
+ // El destructivo es un relleno de otro color: misma tinta blanca, mismo apagado.
35
+ const relleno = modo !== "contorno";
36
+ const tinta = relleno ? c.sobrePrimario : c.primary;
37
+
38
+ return (
39
+ <Pressable
40
+ onPress={onPress}
41
+ disabled={inactivo}
42
+ accessibilityRole="button"
43
+ accessibilityState={{ disabled: !!inactivo, busy: !!cargando }}
44
+ style={({ pressed }) => [
45
+ styles.boton,
46
+ relleno
47
+ ? modo === "destructivo"
48
+ ? styles.destructivo
49
+ : modo === "listo"
50
+ ? styles.listo
51
+ : styles.relleno
52
+ : styles.contorno,
53
+ inactivo && (relleno ? styles.rellenoInactivo : styles.contornoInactivo),
54
+ pressed && { opacity: 0.85 },
55
+ ]}
56
+ >
57
+ <View style={styles.fila}>
58
+ {cargando ? (
59
+ <ActivityIndicator color={tinta} />
60
+ ) : icono ? (
61
+ <IconoDeRenglon
62
+ name={icono}
63
+ fontSize={tipografia.subtitulo}
64
+ size={26}
65
+ color={inactivo ? c.secondaryLight : tinta}
66
+ />
67
+ ) : null}
68
+ <Text style={[styles.texto, { color: inactivo ? c.secondaryLight : tinta }]}>
69
+ {children}
70
+ </Text>
71
+ </View>
72
+ </Pressable>
73
+ );
74
+ };
75
+
76
+ const useStyles = crearEstilos((c) => ({
77
+ boton: {
78
+ minHeight: 64,
79
+ borderRadius: 14,
80
+ paddingVertical: 14,
81
+ paddingHorizontal: 18,
82
+ justifyContent: "center",
83
+ },
84
+ relleno: { backgroundColor: c.primary },
85
+ destructivo: { backgroundColor: c.primaryDark },
86
+ // Un relleno con letra blanca: el verde oscuro se lee igual en los dos modos.
87
+ listo: { backgroundColor: "#2e7d32" },
88
+ rellenoInactivo: { backgroundColor: c.secondaryLighter },
89
+ contorno: { borderWidth: 2, borderColor: c.primary, backgroundColor: c.superficie },
90
+ contornoInactivo: { borderColor: c.secondaryLighter },
91
+ fila: { flexDirection: "row", alignItems: "flex-start", justifyContent: "center", gap: 10 },
92
+ texto: {
93
+ flexShrink: 1,
94
+ ...renglon(tipografia.subtitulo),
95
+ fontWeight: "800",
96
+ textAlign: "center",
97
+ },
98
+ }));
99
+
100
+ export default BotonGrande;
@@ -0,0 +1,69 @@
1
+ import AccionesDelEncabezado, {
2
+ type AccionDelEncabezado,
3
+ } from "../componentes/AccionesDelEncabezado";
4
+ import { Text } from "../texto";
5
+ import { crearEstilos, tipografia, usePaleta } from "../tema";
6
+ import MaterialIcons from "@expo/vector-icons/MaterialIcons";
7
+ import { router } from "expo-router";
8
+ import type React from "react";
9
+ import { TouchableOpacity, View } from "react-native";
10
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
11
+
12
+ /**
13
+ * La cabecera de una pantalla empujada encima de las pestañas: atrás, el rótulo, el título y, si
14
+ * hay, sus acciones a la derecha (`AccionesDelEncabezado`). La usan las fichas, las
15
+ * pantallas de edición y el perfil.
16
+ *
17
+ * `estado` va debajo del título —el estado de la ficha, normalmente un `Chip`— y no a su lado: con
18
+ * acciones a la derecha, un folio largo y su chip en el mismo renglón se peleaban el ancho.
19
+ */
20
+ const CabeceraEmpujada = ({
21
+ eyebrow,
22
+ titulo,
23
+ acciones,
24
+ estado,
25
+ }: {
26
+ eyebrow: string;
27
+ titulo: string;
28
+ acciones?: AccionDelEncabezado[];
29
+ estado?: React.ReactNode;
30
+ }) => {
31
+ const c = usePaleta();
32
+ const styles = useStyles();
33
+ const insets = useSafeAreaInsets();
34
+ return (
35
+ <View style={[styles.hdr, { paddingTop: insets.top + 10 }]}>
36
+ <View style={styles.hdrRow}>
37
+ <TouchableOpacity onPress={() => router.back()} accessibilityLabel="Atrás">
38
+ <MaterialIcons name="arrow-back" size={45} color={c.primary} />
39
+ </TouchableOpacity>
40
+ {/* `flexShrink` y no `flex`: con acciones, el título les deja su hueco. */}
41
+ <View style={acciones?.length ? styles.tituloConAcciones : styles.titulo}>
42
+ <Text style={styles.hdrEyebrow}>{eyebrow}</Text>
43
+ <Text style={styles.hdrTitle}>{titulo}</Text>
44
+ {estado ? <View style={styles.estado}>{estado}</View> : null}
45
+ </View>
46
+ {acciones?.length ? <AccionesDelEncabezado acciones={acciones} /> : null}
47
+ </View>
48
+ </View>
49
+ );
50
+ };
51
+
52
+ const useStyles = crearEstilos((c) => ({
53
+ hdr: { paddingHorizontal: 18, paddingBottom: 13, backgroundColor: c.superficie },
54
+ hdrRow: { flexDirection: "row", alignItems: "flex-end", gap: 8 },
55
+ titulo: { flex: 1, minWidth: 0 },
56
+ tituloConAcciones: { flexShrink: 1, minWidth: 0 },
57
+ hdrEyebrow: {
58
+ fontSize: tipografia.etiqueta,
59
+ color: c.secondaryLight,
60
+ textTransform: "uppercase",
61
+ letterSpacing: 1.6,
62
+ marginBottom: 4,
63
+ fontWeight: "600",
64
+ },
65
+ hdrTitle: { fontSize: tipografia.titulo, fontWeight: "900", color: c.primary },
66
+ estado: { marginTop: 6, flexDirection: "row", flexWrap: "wrap", gap: 6 },
67
+ }));
68
+
69
+ export default CabeceraEmpujada;
@@ -0,0 +1,60 @@
1
+ import { Text } from "../texto";
2
+ import { crearEstilos, type Paleta, renglon, tipografia, usePaleta } from "../tema";
3
+ import { View, type StyleProp, type ViewStyle } from "react-native";
4
+
5
+ /**
6
+ * El tono de un chip, por lo que quiere decir y no por su color: así un estado se ve igual en
7
+ * claro y en oscuro, y dos pantallas no le ponen dos colores a lo mismo.
8
+ */
9
+ export type TonoDeChip = "exito" | "aviso" | "info" | "error" | "morado" | "neutro" | "primario";
10
+
11
+ const colores = (c: Paleta, tono: TonoDeChip) => {
12
+ switch (tono) {
13
+ case "exito":
14
+ return c.exito;
15
+ case "aviso":
16
+ return { fondo: c.aviso.fondo, tinta: c.aviso.tinta };
17
+ case "info":
18
+ return c.info;
19
+ case "error":
20
+ return c.error;
21
+ case "morado":
22
+ return c.morado;
23
+ case "primario":
24
+ return { fondo: c.primary, tinta: c.sobrePrimario };
25
+ default:
26
+ return { fondo: c.superficieTenue, tinta: c.secondary };
27
+ }
28
+ };
29
+
30
+ /** Un estado en una pastilla: «En progreso», «Por vencer», «En viaje». */
31
+ const Chip = ({
32
+ texto,
33
+ tono = "neutro",
34
+ style,
35
+ }: {
36
+ texto: string;
37
+ tono?: TonoDeChip;
38
+ style?: StyleProp<ViewStyle>;
39
+ }) => {
40
+ const c = usePaleta();
41
+ const styles = useStyles();
42
+ const { fondo, tinta } = colores(c, tono);
43
+ return (
44
+ <View style={[styles.chip, { backgroundColor: fondo }, style]}>
45
+ <Text style={[styles.texto, { color: tinta }]}>{texto}</Text>
46
+ </View>
47
+ );
48
+ };
49
+
50
+ const useStyles = crearEstilos(() => ({
51
+ chip: {
52
+ alignSelf: "flex-start",
53
+ paddingHorizontal: 9,
54
+ paddingVertical: 3,
55
+ borderRadius: 999,
56
+ },
57
+ texto: { ...renglon(tipografia.etiqueta), fontWeight: "700" },
58
+ }));
59
+
60
+ export default Chip;
@@ -0,0 +1,53 @@
1
+ import React from "react";
2
+ import { useWindowDimensions, View } from "react-native";
3
+ import { KeyboardAvoidingView } from "react-native-keyboard-controller";
4
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
5
+ import { crearEstilos } from "../tema";
6
+
7
+ interface Props {
8
+ children: React.ReactNode;
9
+ paddingBottom?: number;
10
+ /**
11
+ * Cuando el hijo ya maneja el teclado por su cuenta (p. ej. un `KeyboardAwareScrollView`),
12
+ * `false` quita el `KeyboardAvoidingView` para no encimar dos manejadores del teclado.
13
+ */
14
+ avoidKeyboard?: boolean;
15
+ }
16
+
17
+ const BASE_PADDING = 20;
18
+
19
+ /**
20
+ * El cuerpo de una pantalla debajo de su header: el fondo, el margen a los lados (el doble en una
21
+ * tableta, más lo que pida la muesca) y, por omisión, que esquive el teclado.
22
+ */
23
+ const ContenidoDePantalla = ({ paddingBottom, avoidKeyboard = true, children }: Props) => {
24
+ const styles = useStyles();
25
+ const insets = useSafeAreaInsets();
26
+ const { width } = useWindowDimensions();
27
+ const horizontalPadding = width > 700 ? BASE_PADDING * 2 : BASE_PADDING;
28
+ const containerStyle = [
29
+ styles.container,
30
+ {
31
+ paddingTop: 20,
32
+ paddingLeft: horizontalPadding + insets.left,
33
+ paddingRight: horizontalPadding + insets.right,
34
+ paddingBottom: paddingBottom ?? 0,
35
+ },
36
+ ];
37
+ if (!avoidKeyboard) {
38
+ return <View style={containerStyle}>{children}</View>;
39
+ }
40
+ return (
41
+ // `behavior="padding"` funciona en ambas plataformas con edge-to-edge
42
+ // gracias a react-native-keyboard-controller (RN lo ignora en Android).
43
+ <KeyboardAvoidingView behavior="padding" style={containerStyle}>
44
+ {children}
45
+ </KeyboardAvoidingView>
46
+ );
47
+ };
48
+
49
+ const useStyles = crearEstilos((c) => ({
50
+ container: { flex: 1, backgroundColor: c.fondo },
51
+ }));
52
+
53
+ export default ContenidoDePantalla;
@@ -0,0 +1,45 @@
1
+ import { crearEstilos, renglon, tipografia, usePaleta } from "../tema";
2
+ import { Text } from "../texto";
3
+ import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
4
+ import React from "react";
5
+ import { View } from "react-native";
6
+
7
+ interface Props {
8
+ icono: React.ComponentProps<typeof MaterialCommunityIcons>["name"];
9
+ titulo: string;
10
+ texto?: string;
11
+ /** Una acción («Reintentar») que va debajo del texto, centrada con él. */
12
+ children?: React.ReactNode;
13
+ }
14
+
15
+ /**
16
+ * Lo que se pinta cuando una lista no tiene nada que enseñar. Ocupa todo el alto y centra lo suyo,
17
+ * así que una acción va como hijo: puesta después, como hermano, quedaba hasta abajo de la
18
+ * pantalla, debajo de la barra de pestañas.
19
+ */
20
+ const EstadoVacio = ({ icono, titulo, texto, children }: Props) => {
21
+ const c = usePaleta();
22
+ const styles = useStyles();
23
+ return (
24
+ <View style={styles.root}>
25
+ <MaterialCommunityIcons name={icono} size={56} color={c.secondaryLight} />
26
+ <Text style={styles.titulo}>{titulo}</Text>
27
+ {texto ? <Text style={styles.texto}>{texto}</Text> : null}
28
+ {children ? <View style={styles.accion}>{children}</View> : null}
29
+ </View>
30
+ );
31
+ };
32
+
33
+ const useStyles = crearEstilos((c) => ({
34
+ root: { flex: 1, alignItems: "center", justifyContent: "center", gap: 10, padding: 24 },
35
+ titulo: {
36
+ ...renglon(tipografia.subtitulo),
37
+ fontWeight: "700",
38
+ color: c.secondaryDark,
39
+ textAlign: "center",
40
+ },
41
+ texto: { fontSize: tipografia.cuerpo, color: c.secondary, textAlign: "center" },
42
+ accion: { alignSelf: "stretch", marginTop: 14 },
43
+ }));
44
+
45
+ export default EstadoVacio;