@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
package/src/index.ts ADDED
@@ -0,0 +1,143 @@
1
+ // ==============================|| TEMA ||============================== //
2
+
3
+ export * from "./tema";
4
+ export { Text, TextInput } from "./texto";
5
+
6
+ // ==============================|| COMPONENTES ||============================== //
7
+
8
+ export {
9
+ default as AccionesDelEncabezado,
10
+ type AccionDelEncabezado,
11
+ } from "./componentes/AccionesDelEncabezado";
12
+ export { default as BotonDeAvatar, inicialesDe } from "./componentes/BotonDeAvatar";
13
+ export { default as BotonGrande } from "./componentes/BotonGrande";
14
+ export { default as CabeceraEmpujada } from "./componentes/CabeceraEmpujada";
15
+ export { default as Chip, type TonoDeChip } from "./componentes/Chip";
16
+ export { default as ContenidoDePantalla } from "./componentes/ContenidoDePantalla";
17
+ export { default as EstadoVacio } from "./componentes/EstadoVacio";
18
+ export {
19
+ default as Foto,
20
+ ProveedorDeFotos,
21
+ type BajarFoto,
22
+ type FotoAVer,
23
+ } from "./componentes/Foto";
24
+ export { default as IconoDeRenglon } from "./componentes/IconoDeRenglon";
25
+ export { Logo, LogoCompleto } from "./componentes/Logo";
26
+ export { default as Nota } from "./componentes/Nota";
27
+ export { default as OpcionesExcluyentes } from "./componentes/OpcionesExcluyentes";
28
+ export {
29
+ default as PantallaDeError,
30
+ type PropsDePantallaDeError,
31
+ } from "./componentes/PantallaDeError";
32
+ export { default as Pestanas, type Pestana } from "./componentes/Pestanas";
33
+ export { default as Rotulo } from "./componentes/Rotulo";
34
+ export { default as RotuloDeSeccion } from "./componentes/RotuloDeSeccion";
35
+ export { default as Tarjeta } from "./componentes/Tarjeta";
36
+ export { default as TarjetaDeDatos } from "./componentes/TarjetaDeDatos";
37
+ export { default as TiraDeFotos, type FotoDeLaTira } from "./componentes/TiraDeFotos";
38
+ export { default as VisorDeFoto } from "./componentes/VisorDeFoto";
39
+
40
+ // ==============================|| DIÁLOGOS ||============================== //
41
+
42
+ export {
43
+ avisar,
44
+ confirmar,
45
+ mostrarDialogo,
46
+ type BotonDeDialogo,
47
+ type Dialogo,
48
+ type EstiloDeBoton,
49
+ } from "./dialogos/dialogos";
50
+ export { default as HostDeDialogos } from "./dialogos/HostDeDialogos";
51
+
52
+ // ==============================|| NAVEGACIÓN ||============================== //
53
+
54
+ export { default as BarraDePestanas, HUECO_DE_LA_BARRA } from "./navegacion/BarraDePestanas";
55
+ export type { IconoDePestana } from "./navegacion/BotonDeBarra";
56
+ export {
57
+ ALTO_DEL_ENCABEZADO,
58
+ TituloDelEncabezado,
59
+ useOpcionesDelEncabezado,
60
+ } from "./navegacion/encabezado";
61
+
62
+ // ==============================|| FORMULARIOS ||============================== //
63
+
64
+ export {
65
+ CampoDeFecha,
66
+ CampoDeFechaHora,
67
+ CampoDeOpciones,
68
+ CampoDeTelefono,
69
+ CampoDeTexto,
70
+ CampoInterruptor,
71
+ Campo,
72
+ ErrorDelCampo,
73
+ } from "./formularios/campos";
74
+ export { default as CampoDeSeleccion, CampoDeVarias } from "./formularios/CampoDeSeleccion";
75
+ export {
76
+ FechaControlada,
77
+ FechaHoraControlada,
78
+ InterruptorControlado,
79
+ OpcionesControladas,
80
+ SeleccionControlada,
81
+ TelefonoControlado,
82
+ TextoControlado,
83
+ VariasControladas,
84
+ type CampoAtado,
85
+ type SinValor,
86
+ } from "./formularios/controlados";
87
+ export { mensajeDeError, setErrors } from "./formularios/errores";
88
+ export {
89
+ fechaONula,
90
+ isoONulo,
91
+ mismoInstante,
92
+ soloLoQueCambio,
93
+ textoONulo,
94
+ useGuardado,
95
+ volcarErrores,
96
+ } from "./formularios/guardado";
97
+ export {
98
+ default as SelectorDeOpcion,
99
+ SelectorDeVarias,
100
+ type Opcion,
101
+ type PropsDeSelectorDeOpcion,
102
+ type PropsDeSelectorDeVarias,
103
+ } from "./formularios/SelectorDeOpcion";
104
+ export { default as TextoDeAccesoControlado } from "./formularios/TextoDeAccesoControlado";
105
+ export { useBusqueda } from "./formularios/useBusqueda";
106
+
107
+ // ==============================|| LISTAS Y FICHAS ||============================== //
108
+
109
+ export {
110
+ default as HojaDeFiltros,
111
+ InterruptorDeFiltro,
112
+ OpcionDeFiltro,
113
+ OpcionesMultiples,
114
+ OrdenDeLista,
115
+ SeccionDeFiltros,
116
+ } from "./listas/HojaDeFiltros";
117
+ export { default as ListaPaginada, type ConsultaPaginada } from "./listas/ListaPaginada";
118
+ export { renglonesDe, type Pagina } from "./listas/paginado";
119
+ export {
120
+ AvisoDeRecortados,
121
+ Buscador,
122
+ CabeceraDeLista,
123
+ EstadoDeHoja,
124
+ FilaConContador,
125
+ RenglonDeContacto,
126
+ RenglonDeHoja,
127
+ RenglonDeLiga,
128
+ SeccionDeFicha,
129
+ TarjetaDeLista,
130
+ type FiltrosDeCabecera,
131
+ } from "./listas/piezas";
132
+ export { default as TarjetaDeslizable, type AccionDeslizable } from "./listas/TarjetaDeslizable";
133
+
134
+ // ==============================|| PANTALLAS ||============================== //
135
+
136
+ export {
137
+ default as PantallaDeAcceso,
138
+ type DatosDeAcceso,
139
+ type ResultadoDeAcceso,
140
+ } from "./pantallas/PantallaDeAcceso";
141
+ export { EsperaDeEdicion, FormularioDeEdicion } from "./pantallas/PantallaDeEdicion";
142
+ export { default as PantallaDeFicha } from "./pantallas/PantallaDeFicha";
143
+ export { default as PantallaDePerfil } from "./pantallas/PantallaDePerfil";
@@ -0,0 +1,261 @@
1
+ import BotonGrande from "../componentes/BotonGrande";
2
+ import IconoDeRenglon from "../componentes/IconoDeRenglon";
3
+ import { crearEstilos, renglon, tipografia, usePaleta } from "../tema";
4
+ import { Text } from "../texto";
5
+ import MaterialIcons from "@expo/vector-icons/MaterialIcons";
6
+ import React from "react";
7
+ import { Modal, Pressable, ScrollView, Switch, TouchableOpacity, View } from "react-native";
8
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
9
+
10
+ /**
11
+ * La hoja de filtros y orden de una lista (viajes, recursos), a pantalla completa
12
+ * como la del mapa: con la letra al 180% un menú deja ver dos opciones. Se aplica al tocar, sin
13
+ * «Aplicar»; el botón de abajo dice cuántos renglones quedan. Cada lista pone sus secciones.
14
+ */
15
+ export default function HojaDeFiltros({
16
+ abierta,
17
+ onCerrar,
18
+ hayAlgo,
19
+ onQuitar,
20
+ visibles,
21
+ nombres,
22
+ children,
23
+ }: {
24
+ abierta: boolean;
25
+ onCerrar: () => void;
26
+ /** Si hay algo puesto (un filtro o un orden distinto): ofrece «Quitar». */
27
+ hayAlgo: boolean;
28
+ onQuitar: () => void;
29
+ /** Cuántos quedan con todo lo puesto; `null` mientras se cuentan. */
30
+ visibles: number | null;
31
+ /** Cómo se dice uno y varios: `["viaje", "viajes"]`. */
32
+ nombres: readonly [string, string];
33
+ children: React.ReactNode;
34
+ }) {
35
+ const c = usePaleta();
36
+ const styles = useStyles();
37
+ const insets = useSafeAreaInsets();
38
+ return (
39
+ <Modal visible={abierta} animationType="slide" onRequestClose={onCerrar}>
40
+ <View style={[styles.hoja, { paddingTop: insets.top + 10 }]}>
41
+ <View style={styles.cabecera}>
42
+ <TouchableOpacity onPress={onCerrar} accessibilityLabel="Cerrar">
43
+ <MaterialIcons name="arrow-back" size={45} color={c.primary} />
44
+ </TouchableOpacity>
45
+ <Text style={styles.titulo}>Filtros</Text>
46
+ {hayAlgo ? (
47
+ <TouchableOpacity onPress={onQuitar}>
48
+ <Text style={styles.limpiar}>Quitar</Text>
49
+ </TouchableOpacity>
50
+ ) : null}
51
+ </View>
52
+
53
+ <ScrollView contentContainerStyle={styles.contenido}>{children}</ScrollView>
54
+
55
+ <View style={{ paddingBottom: insets.bottom + 16 }}>
56
+ <BotonGrande onPress={onCerrar}>
57
+ {visibles === null
58
+ ? "Listo"
59
+ : `Ver ${visibles} ${visibles === 1 ? nombres[0] : nombres[1]}`}
60
+ </BotonGrande>
61
+ </View>
62
+ </View>
63
+ </Modal>
64
+ );
65
+ }
66
+
67
+ /** El rótulo de una sección de la hoja. */
68
+ export function SeccionDeFiltros({ children }: { children: string }) {
69
+ const styles = useStyles();
70
+ return <Text style={styles.seccion}>{children}</Text>;
71
+ }
72
+
73
+ /** Una opción como renglón: casilla (de varias) o círculo (de una), como la hoja del mapa. */
74
+ export function OpcionDeFiltro({
75
+ texto,
76
+ elegida,
77
+ unica = false,
78
+ onPress,
79
+ }: {
80
+ texto: string;
81
+ elegida: boolean;
82
+ unica?: boolean;
83
+ onPress: () => void;
84
+ }) {
85
+ const c = usePaleta();
86
+ const styles = useStyles();
87
+ return (
88
+ <Pressable
89
+ onPress={onPress}
90
+ accessibilityRole={unica ? "radio" : "checkbox"}
91
+ accessibilityState={{ checked: elegida }}
92
+ style={[styles.opcion, elegida && styles.opcionElegida]}
93
+ >
94
+ <IconoDeRenglon
95
+ name={
96
+ unica
97
+ ? elegida
98
+ ? "radiobox-marked"
99
+ : "radiobox-blank"
100
+ : elegida
101
+ ? "checkbox-marked"
102
+ : "checkbox-blank-outline"
103
+ }
104
+ fontSize={tipografia.subtitulo}
105
+ color={elegida ? c.primary : c.secondary}
106
+ />
107
+ <Text style={styles.opcionTexto}>{texto}</Text>
108
+ </Pressable>
109
+ );
110
+ }
111
+
112
+ /** Varias opciones de un mismo filtro, cada una se prende y se apaga sola. */
113
+ export function OpcionesMultiples<V extends string | number>({
114
+ titulo,
115
+ opciones,
116
+ elegidas,
117
+ onCambiar,
118
+ }: {
119
+ titulo: string;
120
+ opciones: readonly { value: V; label: string }[];
121
+ elegidas: V[];
122
+ onCambiar: (elegidas: V[]) => void;
123
+ }) {
124
+ return (
125
+ <>
126
+ <SeccionDeFiltros>{titulo}</SeccionDeFiltros>
127
+ {opciones.map((o) => (
128
+ <OpcionDeFiltro
129
+ key={String(o.value)}
130
+ texto={o.label}
131
+ elegida={elegidas.includes(o.value)}
132
+ onPress={() =>
133
+ onCambiar(
134
+ elegidas.includes(o.value)
135
+ ? elegidas.filter((v) => v !== o.value)
136
+ : [...elegidas, o.value],
137
+ )
138
+ }
139
+ />
140
+ ))}
141
+ </>
142
+ );
143
+ }
144
+
145
+ /** Un filtro de sí o no: el renglón entero lo alterna, no sólo el interruptor. */
146
+ export function InterruptorDeFiltro({
147
+ texto,
148
+ prendido,
149
+ onCambiar,
150
+ }: {
151
+ texto: string;
152
+ prendido: boolean;
153
+ onCambiar: (prendido: boolean) => void;
154
+ }) {
155
+ const c = usePaleta();
156
+ const styles = useStyles();
157
+ return (
158
+ <Pressable
159
+ onPress={() => onCambiar(!prendido)}
160
+ accessibilityRole="switch"
161
+ accessibilityState={{ checked: prendido }}
162
+ style={[styles.opcion, styles.interruptor, prendido && styles.opcionElegida]}
163
+ >
164
+ <Text style={styles.opcionTexto}>{texto}</Text>
165
+ <Switch
166
+ value={prendido}
167
+ onValueChange={onCambiar}
168
+ trackColor={{ true: c.primaryLight }}
169
+ thumbColor={prendido ? c.primary : undefined}
170
+ />
171
+ </Pressable>
172
+ );
173
+ }
174
+
175
+ /**
176
+ * «Ordenar por» y su sentido. `orden` es el `ordering` que se manda (`-codigo`), o `undefined` si
177
+ * se deja el del servidor; con `porOmision`, ese «sin orden» se ofrece como opción.
178
+ */
179
+ export function OrdenDeLista({
180
+ campos,
181
+ orden,
182
+ onOrdenar,
183
+ porOmision,
184
+ }: {
185
+ campos: readonly { value: string; label: string }[];
186
+ orden: string | undefined;
187
+ /** El nuevo `ordering`, o `null` para el del servidor. */
188
+ onOrdenar: (orden: string | null) => void;
189
+ porOmision?: string;
190
+ }) {
191
+ const descendente = orden?.startsWith("-") ?? false;
192
+ const campo = orden?.replace(/^-/, "");
193
+ return (
194
+ <>
195
+ <SeccionDeFiltros>Ordenar por</SeccionDeFiltros>
196
+ {porOmision ? (
197
+ <OpcionDeFiltro
198
+ texto={porOmision}
199
+ unica
200
+ elegida={orden === undefined}
201
+ onPress={() => onOrdenar(null)}
202
+ />
203
+ ) : null}
204
+ {campos.map((c) => (
205
+ <OpcionDeFiltro
206
+ key={c.value}
207
+ texto={c.label}
208
+ unica
209
+ elegida={campo === c.value}
210
+ onPress={() => onOrdenar(`${descendente ? "-" : ""}${c.value}`)}
211
+ />
212
+ ))}
213
+ {campo !== undefined ? (
214
+ <>
215
+ <SeccionDeFiltros>Sentido</SeccionDeFiltros>
216
+ <OpcionDeFiltro
217
+ texto="Ascendente"
218
+ unica
219
+ elegida={!descendente}
220
+ onPress={() => onOrdenar(campo)}
221
+ />
222
+ <OpcionDeFiltro
223
+ texto="Descendente"
224
+ unica
225
+ elegida={descendente}
226
+ onPress={() => onOrdenar(`-${campo}`)}
227
+ />
228
+ </>
229
+ ) : null}
230
+ </>
231
+ );
232
+ }
233
+
234
+ const useStyles = crearEstilos((c) => ({
235
+ hoja: { flex: 1, backgroundColor: c.fondo, paddingHorizontal: 18, gap: 12 },
236
+ cabecera: { flexDirection: "row", alignItems: "center", gap: 8 },
237
+ titulo: { flex: 1, fontSize: tipografia.titulo, fontWeight: "900", color: c.primary },
238
+ limpiar: { ...renglon(tipografia.cuerpo), fontWeight: "700", color: c.primary },
239
+ contenido: { gap: 8, paddingBottom: 16 },
240
+ seccion: {
241
+ ...renglon(tipografia.etiqueta),
242
+ fontWeight: "800",
243
+ color: c.secondary,
244
+ textTransform: "uppercase",
245
+ letterSpacing: 0.8,
246
+ marginTop: 10,
247
+ },
248
+ opcion: {
249
+ flexDirection: "row",
250
+ alignItems: "flex-start",
251
+ gap: 10,
252
+ backgroundColor: c.superficie,
253
+ borderRadius: 14,
254
+ borderWidth: 2,
255
+ borderColor: c.secondaryLighter,
256
+ padding: 12,
257
+ },
258
+ opcionElegida: { borderColor: c.primary, backgroundColor: c.primaryWash },
259
+ interruptor: { alignItems: "center" },
260
+ opcionTexto: { flex: 1, ...renglon(tipografia.subtitulo), fontWeight: "700", color: c.texto },
261
+ }));
@@ -0,0 +1,117 @@
1
+ import BotonGrande from "../componentes/BotonGrande";
2
+ import EstadoVacio from "../componentes/EstadoVacio";
3
+ import { crearEstilos, renglon, tipografia, usePaleta } from "../tema";
4
+ import { HUECO_DE_LA_BARRA } from "../navegacion/BarraDePestanas";
5
+ import { Text } from "../texto";
6
+ import type MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
7
+ import React from "react";
8
+ import { ActivityIndicator, FlatList, RefreshControl } from "react-native";
9
+ import { renglonesDe, type Pagina } from "./paginado";
10
+
11
+ /** Lo que la lista lee de un `use…InfiniteQuery` de RTK Query. */
12
+ export interface ConsultaPaginada<T> {
13
+ data?: { pages: Pagina<T>[] };
14
+ isLoading: boolean;
15
+ isError: boolean;
16
+ isFetching: boolean;
17
+ isFetchingNextPage: boolean;
18
+ hasNextPage: boolean;
19
+ fetchNextPage: () => unknown;
20
+ refetch: () => unknown;
21
+ }
22
+
23
+ interface Props<T> {
24
+ consulta: ConsultaPaginada<T>;
25
+ renderItem: (item: T) => React.ReactElement;
26
+ llave: (item: T) => string | number;
27
+ /** Lo que se dice sin renglones: «Ningún viaje en curso». */
28
+ vacio: {
29
+ icono: React.ComponentProps<typeof MaterialCommunityIcons>["name"];
30
+ titulo: string;
31
+ texto?: string;
32
+ };
33
+ /** Cómo se cuentan: `["viaje", "viajes"]` → «128 viajes». */
34
+ nombres: [string, string];
35
+ }
36
+
37
+ /**
38
+ * Una lista **paginada con scroll infinito**: pide la página siguiente al acercarse
39
+ * al final, se refresca jalando hacia abajo y dice cuántos hay en total. Lo que la llena es de
40
+ * quien la usa (`renderItem`); el buscador y las pestañas van arriba, fuera de ella.
41
+ *
42
+ * Deja libre lo que tapa la barra de pestañas, que flota sobre la pantalla.
43
+ */
44
+ export default function ListaPaginada<T>({
45
+ consulta,
46
+ renderItem,
47
+ llave,
48
+ vacio,
49
+ nombres,
50
+ }: Props<T>) {
51
+ const c = usePaleta();
52
+ const styles = useStyles();
53
+ const renglones = renglonesDe(consulta.data);
54
+ const total = consulta.data?.pages[0]?.count;
55
+
56
+ if (consulta.isLoading) {
57
+ return <ActivityIndicator color={c.primary} size="large" style={styles.cargando} />;
58
+ }
59
+ if (consulta.isError && !consulta.data) {
60
+ return (
61
+ <EstadoVacio
62
+ icono="cloud-off-outline"
63
+ titulo="No se pudo cargar"
64
+ texto="Revisa tu señal e intenta de nuevo."
65
+ >
66
+ <BotonGrande icono="refresh" onPress={() => consulta.refetch()}>
67
+ Reintentar
68
+ </BotonGrande>
69
+ </EstadoVacio>
70
+ );
71
+ }
72
+
73
+ return (
74
+ <FlatList
75
+ data={renglones}
76
+ keyExtractor={(item) => String(llave(item))}
77
+ renderItem={({ item }) => renderItem(item)}
78
+ contentContainerStyle={[styles.contenido, !renglones.length && styles.vacia]}
79
+ ListHeaderComponent={
80
+ total !== undefined && renglones.length ? (
81
+ <Text style={styles.total}>
82
+ {total === 1 ? `1 ${nombres[0]}` : `${total} ${nombres[1]}`}
83
+ </Text>
84
+ ) : null
85
+ }
86
+ ListEmptyComponent={
87
+ <EstadoVacio icono={vacio.icono} titulo={vacio.titulo} texto={vacio.texto} />
88
+ }
89
+ ListFooterComponent={
90
+ consulta.isFetchingNextPage ? (
91
+ <ActivityIndicator color={c.primary} style={styles.mas} />
92
+ ) : null
93
+ }
94
+ onEndReachedThreshold={0.5}
95
+ onEndReached={() => {
96
+ if (consulta.hasNextPage && !consulta.isFetching) consulta.fetchNextPage();
97
+ }}
98
+ refreshControl={
99
+ <RefreshControl
100
+ refreshing={consulta.isFetching && !consulta.isFetchingNextPage}
101
+ onRefresh={() => consulta.refetch()}
102
+ colors={[c.primary]}
103
+ progressBackgroundColor={c.superficie}
104
+ />
105
+ }
106
+ keyboardShouldPersistTaps="handled"
107
+ />
108
+ );
109
+ }
110
+
111
+ const useStyles = crearEstilos((c) => ({
112
+ cargando: { marginTop: 40 },
113
+ contenido: { gap: 10, paddingBottom: HUECO_DE_LA_BARRA },
114
+ vacia: { flexGrow: 1 },
115
+ total: { ...renglon(tipografia.secundario), color: c.secondary },
116
+ mas: { marginVertical: 16 },
117
+ }));
@@ -0,0 +1,126 @@
1
+ import { crearEstilos, renglon, tipografia } from "../tema";
2
+ import { Text } from "../texto";
3
+ import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
4
+ import * as Haptics from "expo-haptics";
5
+ import React, { useRef } from "react";
6
+ import { View } from "react-native";
7
+ import ReanimatedSwipeable, {
8
+ SwipeDirection,
9
+ type SwipeableMethods,
10
+ } from "react-native-gesture-handler/ReanimatedSwipeable";
11
+
12
+ /** Lo que mide el panel que asoma al deslizar, y desde dónde ya cuenta como hecho. */
13
+ const ANCHO = 132;
14
+ const UMBRAL = 96;
15
+
16
+ /**
17
+ * El color del panel. **Fijos y no de la paleta**: es un relleno con letra blanca, y los tonos del
18
+ * modo oscuro son claros, para leerse como texto; con blanco encima no se leerían.
19
+ */
20
+ const COLORES = {
21
+ exito: "#2e7d32",
22
+ info: "#1565c0",
23
+ peligro: "#c62828",
24
+ } as const;
25
+
26
+ export interface AccionDeslizable {
27
+ etiqueta: string;
28
+ icono: React.ComponentProps<typeof MaterialCommunityIcons>["name"];
29
+ color: keyof typeof COLORES;
30
+ /** Lo que hace. Quien la da decide si pregunta antes (las que no se deshacen, sí). */
31
+ onAccion: () => void;
32
+ }
33
+
34
+ const Panel = ({ accion, lado }: { accion: AccionDeslizable; lado: "izquierda" | "derecha" }) => {
35
+ const styles = useStyles();
36
+ return (
37
+ <View
38
+ style={[
39
+ styles.panel,
40
+ { backgroundColor: COLORES[accion.color] },
41
+ lado === "izquierda" ? styles.izquierda : styles.derecha,
42
+ ]}
43
+ >
44
+ <MaterialCommunityIcons name={accion.icono} size={26} color="#ffffff" />
45
+ <Text style={styles.etiqueta}>{accion.etiqueta}</Text>
46
+ </View>
47
+ );
48
+ };
49
+
50
+ /**
51
+ * Un renglón de una lista que **hace algo al deslizarlo**: hacia la derecha asoma la acción de la
52
+ * izquierda (`alDeslizarALaDerecha`) y hacia la izquierda la otra. Se suelta pasado el umbral y la
53
+ * acción corre; la tarjeta regresa sola a su lugar. Con una vibración corta, para que se sienta
54
+ * que pasó algo.
55
+ *
56
+ * Sin acciones es la tarjeta de siempre: no hay nada que deslizar.
57
+ */
58
+ export default function TarjetaDeslizable({
59
+ alDeslizarALaDerecha,
60
+ alDeslizarALaIzquierda,
61
+ children,
62
+ }: {
63
+ alDeslizarALaDerecha?: AccionDeslizable | null;
64
+ alDeslizarALaIzquierda?: AccionDeslizable | null;
65
+ children: React.ReactNode;
66
+ }) {
67
+ const styles = useStyles();
68
+ const deslizable = useRef<SwipeableMethods>(null);
69
+
70
+ if (!alDeslizarALaDerecha && !alDeslizarALaIzquierda) return <>{children}</>;
71
+
72
+ return (
73
+ <ReanimatedSwipeable
74
+ ref={deslizable}
75
+ friction={1.5}
76
+ leftThreshold={UMBRAL}
77
+ rightThreshold={UMBRAL}
78
+ overshootLeft={false}
79
+ overshootRight={false}
80
+ containerStyle={styles.contenedor}
81
+ renderLeftActions={
82
+ alDeslizarALaDerecha
83
+ ? () => <Panel accion={alDeslizarALaDerecha} lado="izquierda" />
84
+ : undefined
85
+ }
86
+ renderRightActions={
87
+ alDeslizarALaIzquierda
88
+ ? () => <Panel accion={alDeslizarALaIzquierda} lado="derecha" />
89
+ : undefined
90
+ }
91
+ // `RIGHT`: la tarjeta se fue a la derecha, así que asomó el panel de la izquierda.
92
+ onSwipeableWillOpen={(direccion) => {
93
+ const accion =
94
+ direccion === SwipeDirection.RIGHT
95
+ ? alDeslizarALaDerecha
96
+ : alDeslizarALaIzquierda;
97
+ deslizable.current?.close();
98
+ if (!accion) return;
99
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
100
+ accion.onAccion();
101
+ }}
102
+ >
103
+ {children}
104
+ </ReanimatedSwipeable>
105
+ );
106
+ }
107
+
108
+ const useStyles = crearEstilos(() => ({
109
+ // El redondeo de la tarjeta, para que el panel que asoma no se vea cuadrado detrás.
110
+ contenedor: { borderRadius: 14 },
111
+ panel: {
112
+ width: ANCHO,
113
+ alignItems: "center",
114
+ justifyContent: "center",
115
+ gap: 4,
116
+ paddingHorizontal: 8,
117
+ },
118
+ izquierda: { borderTopLeftRadius: 14, borderBottomLeftRadius: 14 },
119
+ derecha: { borderTopRightRadius: 14, borderBottomRightRadius: 14 },
120
+ etiqueta: {
121
+ ...renglon(tipografia.etiqueta),
122
+ fontWeight: "800",
123
+ color: "#ffffff",
124
+ textAlign: "center",
125
+ },
126
+ }));
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Una página de una lista del servidor (`CustomPagination` de los backends de ACV): `?page=N` y
3
+ * `?page_size=N`, y la respuesta `{count, next, previous, results}`. Las listas la leen de a poco,
4
+ * con scroll infinito (`ListaPaginada`).
5
+ */
6
+ export interface Pagina<T> {
7
+ count: number;
8
+ next: string | null;
9
+ previous: string | null;
10
+ results: T[];
11
+ }
12
+
13
+ /** Todos los renglones cargados hasta ahora, de todas las páginas. */
14
+ export const renglonesDe = <T>(data: { pages: Pagina<T>[] } | undefined): T[] =>
15
+ data?.pages.flatMap((p) => p.results) ?? [];