00:00:00Deja de usar componentes de Radix y pásate a... bueno, a Base UI. De hecho, si eres fan de Shadcn,
00:00:06ya tienes la opción de cambiarte ahora mismo. Si no habías oído hablar de Base UI, en realidad viene
00:00:10de los creadores originales de Radix, Floating UI y Material UI. Es una librería de UI "headless",
00:00:15así que aporta la funcionalidad y accesibilidad de los componentes, pero el diseño lo pones tú,
00:00:20lo cual es muy importante hoy en día, ya que los LLM aún no son tan buenos con los casos especiales
00:00:24y las necesidades de accesibilidad. Pero lo que acabo de describir es exactamente lo que es Radix,
00:00:30¿así que por qué necesitas una nueva? Pues entremos en materia y te mostraré las diferencias clave.
00:00:35Empezaré rápido mostrándote la documentación de Base UI para que veas todos los
00:00:44componentes. A la izquierda verás que tienen prácticamente todos los que
00:00:48necesitarías en tu librería, incluso algunos avanzados como el "combo box" que tenemos aquí,
00:00:52que no puedes conseguir en Radix. Verás que todos tienen un buen ejemplo de cómo
00:00:57hacerlo y darle estilo con algo como módulos CSS; hasta puedes cambiarlo a un
00:01:01ejemplo de Tailwind si quieres. La documentación es muy buena, pero no estamos aquí para
00:01:06comparar la documentación, así que vayamos directos a la primera diferencia clave y la que
00:01:10probablemente más escuches: Base UI se mantiene activamente y Radix está en una especie
00:01:15de estado zombi. Si echamos un vistazo a las gráficas de contribución de GitHub, verás que Base UI
00:01:20crece y crece, mientras que Radix parece recibir un "commit" ocasional, pero queda aún más
00:01:25claro al mirar los PR e incidencias cerradas en el último mes. Puedes
00:01:29ver que Base UI ha cerrado 58 incidencias y fusionado 154 pull requests, mientras que Radix no ha cerrado ni fusionado
00:01:36nada. El resumen de lo que pasó con Radix es que WorkOS compró la empresa detrás de la librería
00:01:42y no invirtió realmente en ella, por lo que el equipo de Radix se fue en gran medida y estamos en este estado.
00:01:47El cocreador de Radix incluso dijo que solo usaría Radix como última opción y, sí, ahora
00:01:53está trabajando en Base UI. Se trata de asegurar que tus aplicaciones y dependencias se mantengan
00:01:58activamente y no te den dolores de cabeza en el futuro si encuentras un error que no se va a
00:02:02solucionar. Y lo mejor es que Base UI se hizo para ser muy similar a Radix, así que la migración no debería ser
00:02:08tan mala, aunque eso no significa que no hayan podido meter algunas mejoras.
00:02:13Una de mis favoritas es cómo han manejado la propiedad "asChild" que tienes en Radix. Si no la has
00:02:17visto antes, aquí tengo un Select de Radix, y si quisiera renderizar un componente personalizado
00:02:22como mi disparador del select, si simplemente lo envolviera con el componente Select Trigger, verás que
00:02:27obtengo un componente envoltorio y luego el botón que dice "Suscribirse" (algo que deberías pulsar, por cierto).
00:02:31Pero si realmente quisiera que el botón de suscripción actuara como el disparador del select,
00:02:36todo lo que necesito hacer en Radix es añadir la propiedad "asChild" al disparador, indicándole
00:02:41a Radix que fusione todas las propiedades y la funcionalidad de este disparador con el componente que
00:02:46hemos puesto como hijo. Puedes ver que ocurre porque el nombre de la clase aquí se está
00:02:50fusionando con el botón y, en este caso, lo está sobrescribiendo. Si borro esa propiedad y
00:02:55guardo, verás que ahora tenemos un botón, pero este funciona como el disparador de mi select.
00:03:00Es una funcionalidad muy útil, pero una queja común era que no resultaba muy
00:03:04explícita. Admito que a veces, al revisar código rápido, se me pasaba
00:03:09esta propiedad y no veía la causa del problema. Si pasamos a ver cómo se hace
00:03:13en Base UI, obtienes exactamente la misma funcionalidad: tengo un botón aquí que
00:03:18actúa como disparador, pero si miras el código, en lugar de usar "asChild", Base UI usa
00:03:24la propiedad "render". En ella especificas el componente que quieres... bueno, renderizar
00:03:29como disparador. Es un cambio menor, pero creo que lo hace
00:03:34mucho más explícito. Literalmente estás renderizando este componente, así que no tienes que
00:03:39mirar si está usando el componente hijo o buscar la propiedad "asChild". Es, como dije,
00:03:43un pequeño cambio, pero muy bueno en mi opinión. Y ese no es todo el poder de la propiedad
00:03:48"render". Vemos aquí que al construir un interruptor (switch), podemos pasar una función a la
00:03:52propiedad "render", lo que nos permite acceder a las propiedades y al estado del componente que estamos
00:03:56construyendo. En este caso, el del control deslizante del interruptor. Esto nos permite elegir qué componente
00:04:01queremos aplicar a las propiedades pasadas y luego podemos aplicar lógica de renderizado
00:04:05o de estilo personalizada basada en el estado del componente. Por ejemplo, con el
00:04:10control del interruptor, podemos ver si está marcado, modificado, deshabilitado, lleno y mucho más. En este
00:04:14caso, simplemente comprobamos si está marcado o no y, si lo está,
00:04:18renderizamos un icono diferente. Incluso hay un "hook" que te permite integrar esa propiedad "render"
00:04:22en tus propios componentes personalizados. Pero nos estamos adelantando un poco, aunque espero que
00:04:27veas que cualquier cosa personalizada que quieras hacer, deberías poder manejarla con Base UI.
00:04:31Volviendo a mi componente select, la siguiente diferencia es que Base UI permite que algunos
00:04:35componentes se basen en datos. Podemos verlo en el select: lo que tengo actualmente
00:04:40es el código del select de Radix. Tenemos un array con nuestra etiqueta y valor, y para
00:04:44meter los valores en el select, lo único que necesitamos es mapear el array de manzanas
00:04:49y luego renderizar un elemento del select en Radix, lo que añadirá estos valores. Si
00:04:54pasamos a cómo se hace en Base UI, verás que es increíblemente similar: seguimos teniendo
00:04:59mi array de etiquetas y valores, y seguimos mapeándolo y renderizando
00:05:03un elemento del select, pero también lo incluimos en otro lugar: en la raíz del select.
00:05:08Incluimos ese array, y esto tiene un impacto sutil: el componente ahora es
00:05:13consciente de los datos que va a renderizar antes de hacerlo. Esto se traduce en un
00:05:17rendimiento ligeramente mejor, especialmente en el renderizado del lado del servidor. Una cosa que creo
00:05:22que podría mejorarse es que, por el momento, paso las manzanas como propiedad "items",
00:05:26pero luego también mapeo el mismo array abajo, así que lo usamos en dos sitios. Lo que
00:05:32creo que deberían hacer es lo que hace React Aria, otra librería "headless": aquí
00:05:36ves que tenemos nuestro array de animales, lo pasamos como "items" y luego, para los
00:05:41hijos, solo usamos una función. Esta conocerá todos los elementos que se han
00:05:45pasado en el elemento padre, así no usamos el array en dos lugares y el elemento
00:05:50padre sirve como proveedor de datos. Es algo que creo que aún se podría mejorar
00:05:55un poco, pero volvamos al select para mostrarte otra diferencia,
00:05:59aunque esta es específica del componente select (la propiedad "render" y el enfoque basado en
00:06:03datos los verás en casi todos los componentes). Esta es específica de select:
00:06:08puedes tener selección múltiple. Esto es algo que se echaba mucho de menos en Radix.
00:06:13Como ves, en Base UI solo tienes que añadir al select la propiedad "multiple"
00:06:17como verdadera o falsa, y tu select se vuelve múltiple. Así de fácil. Y para
00:06:22ir un paso más allá, Base UI incluso tiene otros componentes que faltan en Radix, como un combo
00:06:27box y autocompletado; es la ventaja de mantenerse activamente: pueden responder
00:06:33a las peticiones de los usuarios. Hay dos diferencias más que quiero mostrarte entre Radix y Base UI,
00:06:38y cambiaremos al componente de casilla de verificación (checkbox) porque ya me aburrí un poco de
00:06:41aquel componente select. La primera diferencia que quiero mostrarte tiene que ver con el estilo: Base UI
00:06:45te da otra opción de estilo que me parece genial. Aquí ves que de momento
00:06:50estoy usando Tailwind. Puedes usar todos los enfoques tradicionales como CSS normal, módulos
00:06:55CSS y muchos más, pero si usas algo como Tailwind, una de las formas en que
00:06:59sueles dar estilo es usando atributos de datos para el estado. Tenemos "data-checked"
00:07:04aquí, y si está marcado, usaremos el fondo primario. Como ves, tenemos una
00:07:08cadena muy larga de estilos en Tailwind que a veces puede ser un problema. Así que
00:07:13una de las opciones que te da Base UI para ayudar con esto es usar una función
00:07:17como nombre de clase. Esto te da acceso al estado del componente; en el caso de la casilla
00:07:22aquí, aplico estilos basándome en si el estado es marcado o deshabilitado. Ves que lo hago
00:07:26con un simple condicional, y a veces creo que es una forma más agradable de ver,
00:07:31de un vistazo rápido al código, de dónde vienen exactamente esos estilos de marcado y deshabilitado,
00:07:35en lugar de tener que escanear esa línea interminable buscando atributos de datos. Creo que
00:07:40es especialmente útil si usas algo como CSS puro. También funciona muy
00:07:45bien con otra librería que me gusta mucho llamada Tailwind Variants. Aquí ves que
00:07:49paso el estado a mi función checkbox, y arriba, en mi variante Tailwind de checkbox, tenemos nuestros
00:07:53estilos base pero también nuestras variantes. Puedes ver que digo: si "checked" es
00:07:58verdadero aplica estos estilos, si "disabled" es verdadero aplica estos otros. Me parece que
00:08:02esto queda mucho más claro que usar atributos de datos, pero depende de tu opinión y de con qué estés
00:08:06cómodo. Es genial que Base UI nos dé todas estas opciones. También
00:08:11añadiré que usar una función como nombre de clase fue algo que me encantó de React
00:08:14Aria. Me parece que tenemos a React Aria por un lado, que tiene una curva de aprendizaje
00:08:19más pronunciada, y a Radix, que es bastante simple; Base UI se ha quedado en el medio, tomando lo
00:08:23que me gusta de ambos para crear la librería "headless" definitiva. Esas son todas
00:08:28las diferencias clave que quería repasar, pero aún hay mucho más: Base UI tiene
00:08:33gran soporte para React Hook Form y TanStack Form, soporte para animaciones para que sea
00:08:38fácil animar tus componentes, e incluso funciones como "input scrubbing",
00:08:42diálogos anidados y menús que se activan al pasar el ratón. Estoy seguro de que si tienes una petición razonable,
00:08:47te responderán en GitHub, ya que se mantiene activamente. Dicho esto, también hay que decir
00:08:52que probablemente no me lanzaría a migrar mi app de Radix a Base UI de inmediato,
00:08:57porque no creo que Radix esté del todo roto. Si empezara un proyecto nuevo, sin duda usaría Base UI ahora,
00:09:02y si necesitara una función como un combo box o autocompletado, también consideraría migrar. Dime
00:09:07qué piensas de Base UI en los comentarios; ya que estás ahí, suscríbete y, como siempre,
00:09:11¡nos vemos en el próximo vídeo!