Skip to main content
Estas recetas amplían la primera app y la feature de clientes. Los recursos y contratos se indican expresamente; adapta su ubicación a las convenciones del consumidor.

Texto multilínea y contraseña

La contraseña ya incluye el control de visibilidad. No añadas un segundo control para la misma decisión. Para un login real, conecta el contrato de autenticación del producto y no realices la petición desde build.

Imágenes: elegir, validar y limpiar

Este componente usa el selector nativo del paquete cuando no recibe pickImage. El callback opcional permite probarlo con una función inyectada o reemplazar el selector. validator comprueba presencia y tamaño; no recorta ni comprime.
Para mostrar una imagen existente puedes pasar imageProvider, por ejemplo un NetworkImage construido con una URL real del producto. El provider no genera bytes para el validator. Define cómo se acepta una imagen existente y cómo se comunica su eliminación al repositorio. Una subida real pertenece al repositorio: recibe bytes o el objeto requerido por el contrato, transforma la respuesta y devuelve un resultado. IsselImagePicker sólo selecciona, muestra y comunica; no sube el archivo al servidor. El límite del validator se comprueba después de leer la imagen en memoria.

Assets locales

Coloca tus imágenes en la app y registra la carpeta:
openProducts es una acción real de presentación. IsselAssetContainer(network: 'dominio', asset: 'respaldo') carga un favicon y necesita también un fallback válido. La guía oficial de assets Flutter explica registro y variantes de resolución.

Fuente del producto

Agrega los archivos de fuente que tengas disponibles a la app:
Las rutas y AppFont son nombres del ejemplo: deben corresponder a archivos reales. La fuente no viene incluida en el paquete. La escala y las alturas existentes se conservan con copyWith.

JSON y entidad separados

Para ilustrar el mapper, esta receta define un contrato de respuesta concreto:
Los campos son del ejemplo y no describen un endpoint incluido en el paquete. El archivo necesita la entidad del formulario de clientes. Un datasource puede usarlo tras recibir el JSON del cliente API real.
La petición no envía el id que asigna el servidor. Si el contrato del backend usa envoltorios, otros nombres o nulabilidad, cambia el datasource/mapper. El repositorio captura AppException, convierte con AppFailure.fromException y retorna AppResult<CustomerEntity>; la vista recibe una entidad, no JSON.

Búsqueda remota: debounce y respuestas antiguas

Este controlador recibe una capacidad de búsqueda inyectada. La función se implementa con el repositorio del producto; aquí no se presupone cliente HTTP ni endpoint. queueSearch programa una consulta y searchNow devuelve su resultado.
Conecta IsselSearchDropdown.onSearchChanged a controller.queueSearch y reconstruye desde AnimatedBuilder. Construye sus DropdownMenuItem con controller.items; presenta carga y error fuera del selector. La revisión se invalida al escribir, incluso mientras espera el debounce, para que una respuesta previa no reemplace la consulta nueva. Descartar una respuesta no cancela la petición del repositorio. Si el cliente dispone de cancelación, integra ese mecanismo en datos y en el ciclo de vida del controlador.
El snippet muestra tres lugares del mismo State; no es un archivo independiente. didChange actualiza el FormField; cambiar sólo selectedType no garantiza la sincronización en esta implementación. Si bloqueas el campo con AbsorbPointer, revisa también navegación por teclado y foco para tu entorno.

Tabla con ancho mínimo

tableWidget es un IsselTableWidget con header y filas válidos. La altura del SizedBox acota el Expanded interno y el scroll horizontal pertenece a la app. Para móvil también puedes utilizar ResponsiveRecords, que cambia de tabla a lista.
Los destinos y efectos pertenecen a presentación. No introduzcas navegación en el repositorio para reutilizar un formulario en página y diálogo.