← Volver a ingeniería
#krodox #livewire

Por qué el panel de Krodox está construido con Flux

Por Krodox Team 6 min de lectura
Por qué el panel de Krodox está construido con Flux

Todo lo que ve un cliente de Krodox después de iniciar sesión (el panel, los ajustes del sitio, las reservas, la facturación, las páginas de la cuenta) está construido con Flux, la librería de componentes creada por el equipo de Livewire. También lo está la consola de operaciones con la que gestionamos la plataforma.

Son unas 170 vistas Blade, 35 componentes distintos de Flux y, en el último recuento, más de 270 botones. Esta es la razón por la que no los hicimos nosotros, y lo que nos ha costado la decisión.

La pregunta nunca fue "qué sistema de diseño"

Krodox es una aplicación Laravel 13 sobre Livewire 4. La interfaz se renderiza en el servidor y se vuelve interactiva con Livewire y Alpine. Lo que usáramos para los componentes tenía que ser componentes Blade, o acabaríamos manteniendo un segundo stack de front-end junto al primero.

Eso dejaba dos opciones reales: escribir nuestro propio juego de componentes o usar Flux.

Escribir los propios parece barato al principio. Un botón son unas cuantas clases. Un campo de texto, unas pocas más. El coste llega después, en los componentes que nadie quiere escribir dos veces: un modal que retiene el foco y lo devuelve al cerrarse, un desplegable que se maneja con el teclado, un selector de hora, un select que funciona en el móvil, un interruptor que un lector de pantalla sabe anunciar. Cada uno es un pequeño proyecto, y cada uno es un comportamiento que nuestros clientes solo notarían cuando fallara.

El dueño de un negocio que cambia su horario a las once de la noche no debería ser quien descubra que nuestro selector de hora casero no se cierra al pulsar Escape.

Cómo se usa

Esta es la fila de alertas de reservas de la página de preferencias de correo, reducida a lo esencial:

<x-home.row
    icon="bell"
    :title="__('messages.settings.email_preferences.booking_notifications.label')"
    :meta="__('messages.settings.email_preferences.booking_notifications.description')"
>
    <x-slot:trailing>
        <flux:switch
            wire:model.live="bookingNotificationsEnabled"
            :aria-label="__('messages.settings.email_preferences.booking_notifications.label')"
        />
    </x-slot:trailing>
</x-home.row>

En pantalla la fila dice "Alertas de reservas", con el texto de apoyo debajo. <x-home.row> es un componente nuestro. Coloca el icono, el título y la descripción a la izquierda y lo que metas en trailing a la derecha. <flux:switch> es el interruptor completo: el marcado, los estados, el manejo del teclado, los atributos de accesibilidad y el enlace con la propiedad de Livewire mediante wire:model.live, que guarda el cambio en cuanto el propietario lo activa. No hay JavaScript escrito para él, y nada en él es específico de esta página.

El mismo patrón vale para un campo de texto, un control segmentado o un select. Mete un control de Flux dentro de una fila y la página se mantiene coherente sin que nadie tenga que recordar una regla.

Los modales son donde se amortiza

Cambiar la dirección de un sitio es arriesgado, así que se hace en un modal de dos pasos. En el primero, abajo, el propietario escribe la nueva dirección y ve si está disponible mientras escribe. En el segundo, el modal muestra la dirección antigua tachada junto a la nueva y avisa de que los visitantes de la dirección antigua se redirigirán durante 30 días. No cambia nada hasta que confirma.

Elegir una nueva dirección: el sitio, el nuevo subdominio y la comprobación de disponibilidad en vivo

El contenido de esos dos pasos lo escribimos nosotros. Flux se encarga de todo lo demás: abrir y cerrar, el foco, la tecla Escape, el botón de cerrar, el fondo, y un segundo paso dentro del mismo diálogo. Usamos decenas de modales en la aplicación y ninguno nos ha obligado a depurar ese comportamiento.

Un acento, una variable

Flux pinta sus interruptores, casillas, botones de opción, enlaces y botones principales con una sola variable CSS, --color-accent. Nosotros apuntamos esa variable a un token propio, y ese token es el único lugar donde se define el acento del panel:

--color-accent:            var(--app-accent);
--color-accent-foreground: var(--app-accent-fg);

Con el estilo de tinta sobre papel del panel, ese acento es casi negro en modo claro y casi blanco en oscuro, con el color de texto correspondiente encima y un tono para el hover. Ninguna vista sabe cuál es el acento. Versiones anteriores dejaban que cada cuenta eligiera uno de cinco temas de color; lo quitamos y, como todas las vistas solo se referían al token, quitarlo supuso borrar las variantes del tema y no cambiar ninguna vista. Ese es el argumento práctico para canalizar el color de una librería por una variable propia.

Tematizar, no bifurcar

Flux permite publicar cualquier componente en tu propio proyecto y editarlo. Hemos tenido cuidado con eso. De los 35 componentes que usamos, hemos publicado dos (la lista de navegación lateral y el toast), además de un juego de iconos propios que Flux muestra junto a los suyos. Todo lo demás se estiliza con tokens.

La razón son las actualizaciones. Un componente publicado es un componente que ahora mantienes tú. Lo que se deja como está recibe sus correcciones y mejoras de accesibilidad con un composer update. Cuando sale una versión nueva de Flux, leemos el changelog, pasamos la batería de tests y la desplegamos.

Lo que cuesta

Sería deshonesto presentarlo como gratis.

Es una licencia de pago. Los componentes en los que más nos apoyamos (el selector de hora, los selects más completos) están en Flux Pro. Para una empresa que construye un solo producto es barato comparado con el tiempo de ingeniería que sustituye, pero es una línea más en el presupuesto.

Nos ata a Livewire. Flux es Blade y Livewire. Si algún día quisiéramos un front-end en React, los componentes no vendrían con nosotros. Lo aceptamos porque toda la plataforma está construida sobre el stack de Laravel, pero es una dependencia real.

Tiene opiniones. Flux tiene su propio espaciado, tamaños y valores por defecto, y a veces nuestro diseño quiere otra cosa. Casi siempre basta con un token. Cuando no, perdemos algo de tiempo trabajando con la librería en lugar de alrededor de ella.

Hay aristas. En una versión, el componente de carrusel traía una clase que nuestra compilación de CSS no sabía interpretar, lo que generaba un aviso en cada build. Usamos el carrusel (en la sección de portafolio de la lista de sitios y en las tiras de capturas de nuestro blog), así que dejamos ese archivo fuera del escaneo de CSS y estilizamos nosotros las partes que necesitamos, como los puntos indicadores. Algo pequeño, pero del tipo que se hereda con cualquier dependencia.

¿La volveríamos a elegir?

Sí. La prueba que aplicamos a una dependencia es si deja que un equipo pequeño dedique su tiempo al producto y no a infraestructura que el cliente nunca ve. En Krodox eso es el flujo de reservas, el editor del sitio y un lanzamiento que tarda alrededor de un minuto y medio. Un modal que se cierra bien no es donde queremos ser ingeniosos.

Si construyes sobre Laravel y Livewire, Flux es la opción por defecto que recomendaríamos. Si no usas Livewire, no es para ti, y ningún tema de color cambia eso.

Lecturas relacionadas

Usamos cookies para mejorar tu experiencia y mantener tus datos seguros. Política de privacidad