Qwik — Tailwind + daisyUI

Pasos a seguir para poder crear un template con Tailwind junto con la librería de componentes más popular daisyUI

Anartz Mugika Ledo🤗
13 min readJun 6, 2023

Comenzamos con un nuevo artículo en el que vamos a aprender a trabajar con TailwindCSS y daisyUI en Qwik, desde el proceso de instalación hasta implementarlo en la práctica.

Para ello, os proporcionaré las instrucciones a seguir para completar todo lo necesario junto con enlaces de refuerzo a la documentación oficial.

Esta información nos será útil para este artículo y en el futuro.

Recordad que vamos haciendo con cierta frecuencia implementaciones de este estilo de cosas que pueden resultar interesantes, si tenéis alguna sugerencia, podéis escribirme.

Os recomiendo leer los artículos anteriores en orden y si practicáis, ¡¡mucho mejor!!.

Recordad, que si hay dudas, aun leyéndolo, podéis preguntarlo en los comentarios y sin dudas me gustaría que me comentéis también, para tener feedback.

Todos los artículos publicados del curso los encontraréis en la siguiente lista que iré actualizando semanalmente y estableciendo el orden natural recomendado:

Qwik paso a paso desde 0 al detalle

23 stories

Si queréis recibir notificaciones sobre este contenido y similares, os animo a que os suscribáis a mi lista de correo:

Solo habrá avisos con nuevos contenidos, es decir, nuevos artículos (1–3 máximo a la semana, generalmente 1).

En este artículo trabajaremos con la versión 1.1.4, que es la versión estable que tenemos en la actualidad (06/06/2023).

El proyecto creado que usaré como base para el artículo es el correspondiente a la plantilla en blanco con el sistema de enrutamiento.

Contenido del artículo

  • Instalar TailwindCSS y daisyUI
  • Navbar
  • Contenedor principal
  • Footer
  • Conclusión

Instalar TailwindCSS y daisyUI

Comenzamos ejecutando el comando para integrar TailwindCSS en nuestro proyecto de Qwik, que simplemente será ejecutar el siguiente comando:

npm run qwik add tailwind

Una vez que ejecutemos el comando, antes de realizar ninguna confirmación (en el punto 2), podemos ver el resumen (1) de los ficheros que se van a modificar, crear y las dependencias que se instalarán en el proyecto.

Para seguir adelante, seleccionamos Yes looks good, finish update

Ahora procedemos a instalar daisyUI:

npm i -D daisyui

Una vez instaladas las dependencias de debemos de hacer una pequeña configuración dentro del fichero de configuración de TailwindCSS de nuestro proyecto, concretamente en el fichero tailwind.config.js

Pasando de lo siguiente:

/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
theme: {
extend: {},
},
plugins: [], // <======== AQUI HACEMOS EL CAMBIO
};

A los siguiente:

/** @type {import('tailwindcss').Config} */
module.exports = {
...
plugins: [require("daisyui")],
};

Ahora que ya tenemos todo listo, iniciamos la ejecución del servidor y como esta con la plantilla en blanco, nos aparecerá algo similar a lo siguiente (evidentemente, con el tiempo esta plantilla puede cambiar):

Todavía no hemos añadido nada usando TailwindCSS ni ningún componente de daisyUI.

Pasamos al siguiente punto y empezamos a trabajar con la estructura de una página principal, en el que vamos a añadir un navbar superior, un footer y dentro un contenedor principal, para trabajar con varias rutas en las que vamos a meter contenido de “relleno” con componentes de daisyUI.

A partir de ahora, vamos a tener a mano estas dos referencias (si las metéis a favoritos, seguro que mejor):

Estas las vamos a utilizar para ir construyendo nuestra página con TailwindCSS y la librería de componentes de CSS de TailwindCSS con daisyUI.

Los cambios efectuados en el proyecto, desde su creación:

https://github.com/Qwik-Spanish/qwik-tailwindcss-daisyui/commit/5477f932f226086c4d85c49fd12e32048bf3cdae

Navbar

Para añadir un navbar, lo primero que vamos a hacer es crear un componente llamado dentro de src/components/core/navbar y dentro de el, un fichero index.tsx con este contenido inicial:

import { component$ } from '@builder.io/qwik';

export default component$(() => {
return <>NAVBAR</>
});

Una vez que ya tenemos ese contenido inicial, lo añadimos en la parte superior dentro de src/routes/layout.tsx, encima de <Slot />

Pasamos de esto:

import { component$, Slot } from '@builder.io/qwik';

export default component$(() => {
return <Slot />;
});

A lo siguiente:

import { component$, Slot } from '@builder.io/qwik';
import Navbar from '~/components/core/navbar';

export default component$(() => {
return <div>
<Navbar />
<Slot />
</div>;
});

Y el resultado será el siguiente:

No ha cambiado mucho la verdad, pero ya tenemos introducido el componente del navbar y ahora vamos a hacer ese cambio mediante este apartado de la documentación de daisyUI para añadir un navbar con opciones de menú y submenús

Accediendo a esa URL, veremos lo siguiente:

Lo que nos interesa (os pueden interesar otras variantes) es el apartado englobado con el trazo verde.

Para coger el contenido del HTML, debemos de hacer click en la pestaña HTML, que está junto con Vista Previa, opción que está activada por defecto:

Nos mostrará el contenido de ese componente (1) y copiamos todo su código (2):

Lo trasladamos a src/components/core/navbar/index.tsx dejando el contenido de ese componente de la siguiente forma:

import { component$ } from '@builder.io/qwik';

export default component$(() => {
return (
<div class='navbar bg-base-100'>
<div class='flex-1'>
<a class='btn btn-ghost normal-case text-xl'>daisyUI</a>
</div>
<div class='flex-none'>
<ul class='menu menu-horizontal px-1'>
<li>
<a>Link</a>
</li>
<li>
<details>
<summary>Parent</summary>
<ul class='p-2 bg-base-100'>
<li>
<a>Link 1</a>
</li>
<li>
<a>Link 2</a>
</li>
</ul>
</details>
</li>
</ul>
</div>
</div>
);
});

Al guardar, se muestra de la siguiente forma:

En este punto, personalmente me gustaría aplicarle otra variante de color y siguiendo esta referencia podemos cambiarlo a las siguientes variantes:

Usando este código como referencia para la apariencia del Navbar:

<div class="navbar bg-neutral text-neutral-content">
<a class="btn btn-ghost normal-case text-xl">daisyUI</a>
</div>

Usaré el primero y haré el siguiente:

  • Sustituir bg-base-100 por bg-neutral text-neutral-content en el div principal del navbar.
  • Sustituir bg-base-100 por bg-neutral text-black en del elemento ul que está dentro del selector details.

El tema de los colores y como trabajar con ello lo podéis encontrar a continuación:

Teniendo en cuenta lo mencionado, pasamos de este código que tenemos actualmente:

import { component$ } from '@builder.io/qwik';

export default component$(() => {
return (
<div class='navbar bg-base-100'> <==== AQUI
<div class='flex-1'>
<a class='btn btn-ghost normal-case text-xl'>daisyUI</a>
</div>
<div class='flex-none'>
<ul class='menu menu-horizontal px-1'>
<li>
<a>Link</a>
</li>
<li>
<details>
<summary>Parent</summary>
<ul class='p-2 bg-base-100'> <======= AQUI
...
</ul>
</details>
</li>
</ul>
</div>
</div>
);
});

A este código:

import { component$ } from '@builder.io/qwik';

export default component$(() => {
return (
<div class='navbar bg-neutral text-neutral-content'>
<div class='flex-1'>
<a class='btn btn-ghost normal-case text-xl'>daisyUI</a>
</div>
<div class='flex-none'>
<ul class='menu menu-horizontal px-1'>
<li>
<a>Link</a>
</li>
<li>
<details>
<summary>Parent</summary>
<ul class='p-2 bg-neutral text-neutral-content'>
<li>
<a>Link 1</a>
</li>
<li>
<a>Link 2</a>
</li>
</ul>
</details>
</li>
</ul>
</div>
</div>
);
});

Obteniendo el siguiente resultado:

Con esto, ya hemos construido la base del navbar de nuestra página con sus estilos y la variante deseada. Para terminar, lo que nos queda es hacer cambios en el contenido.

Cambios:

  • Sustituir daisyUI por el nombre de nuestra marca o nuestro nombre de pila y apellidos.
  • Añadir enlaces. Link sustituimos con Redes sociales donde añadiré contenido de como ponerse en contacto conmigo y en parent añadimos “Componentes” donde por elemento, tendremos ejemplos con diferentes ejemplos en los apartados “Link1”, “Link2”,…

Teniendo esto en cuenta, añadimos una estructura de datos como la siguiente en src/constants/menu.ts adaptada a nuestro nuevo menú principal:

export const menuPrincipalData = {
home: {
title: 'Anartz Mugika Ledo',
url: '/',
},
links: {
social: {
title: 'Redes Sociales',
url: '/social',
},
components: [
{
title: 'Botones',
url: '/components/buttons',
},
{
title: 'Accordion',
url: '/components/accordion',
},
{
title: 'Alerts',
url: '/components/alerts',
},
],
},
};

Con esto, añadimos los datos en el layout, para que ya coja la nueva información desde menuPrincipalData :

import { component$ } from '@builder.io/qwik';
import { Link } from '@builder.io/qwik-city';

// Añadimos para trabajar con la información
import { menuPrincipalData } from '~/constants/menu';

export default component$(() => {
return (
<div class='navbar bg-neutral text-neutral-content'>
<div class='flex-1'>
<Link
class='btn btn-ghost normal-case text-xl'
href={menuPrincipalData.home.url}
>
{menuPrincipalData.home.title}
</Link>
</div>
<div class='flex-none'>
<ul class='menu menu-horizontal px-1'>
<li>
<Link href={menuPrincipalData.links.social.url}>
{menuPrincipalData.links.social.title}
</Link>
</li>
<li>
<details>
<summary>Components</summary>
<ul class='p-2 bg-neutral text-black'>
{menuPrincipalData.links.components.map((link) => (
<li>
<Link href={link.url}>{link.title}</Link>
</li>
))}
</ul>
</details>
</li>
</ul>
</div>
</div>
);
});

Recordad que debemos de tener definidas las rutas con esta estructura:

src/
└── routes/
├── social/
│ └── index.tsx # http://127.0.0.1:5173/social
├── components/
│ └── alerts
│ └── index.tsx # http://127.0.0.1:5173/components/alerts
│ └── buttons
│ └── index.tsx # http://127.0.0.1:5173/components/buttons
│ └── accordion
│ └── index.tsx # http://127.0.0.1:5173/components/accordion
└── index.tsx # http://127.0.0.1:5173/

Y una vez efectuados los cambios, debemos de visualizar algo como lo siguiente, con opción a navegar a las diferentes páginas:

Probad las rutas que tenemos disponibles haciendo click en todas las opciones.

Ahora ya teniendo la parte superior preparada, pasamos al apartado del contenedor principal, donde se irá cargando todas las páginas de las rutas seleccionadas.

Contenedor principal

Lo que vamos a hacer ahora es añadir un contenedor principal, centrado y que sea responsive.

Siguiendo esta referencia:

Añadiremos el siguiente código dentro del fichero layout que encontramos dentro de src/routes/layout.tsx

<!-- Full-width fluid until the `md` breakpoint, then lock to container -->
<div class="md:container md:mx-auto">
<!-- ... -->
</div>

Implementándolo de la siguiente forma:

import { component$, Slot, useStyles$ } from '@builder.io/qwik';
import Navbar from '~/components/core/navbar';

export default component$(() => {
// 1.- Provisional, para ir visualizando como se muestra el contenedor
useStyles$(`
#content {
border: 2px dotted red;
}
`);
// El contenedor añadido, sin espaciado ni margin
return <div>
<Navbar />
<div id="content" class="md:container md:mx-auto">
<Slot />
</div>

</div>;
});

Guardamos los cambios y debe de verse de la siguiente forma:

Ya podemos observar el espacio que ocupa nuestro contenedor principal gracias al estilo con borde que le hemos aplicado de manera temporal.

Este contenedor se adaptará verticalmente dependiendo del contenido que le introduzcamos, y esto no lo vamos a tocar.

Lo que si tocaremos el el margen (margin) que va a tener respecto al navbar y luego el relleno (padding) que necesita aplicarse.

Para poder aplicar estos valores con TailwindCSS, debemos de seguir esta referencia:

Y siguiendo lo que pone ahí, aplicaremos estos valores (esto es subjetivo, podéis hacerlo como más os guste):

"my-6"
margin-top: 1.5rem; /* 24px */
margin-bottom: 1.5rem; /* 24px */

"p-3"
padding: 0.75rem; /* 12px */

En el código se reflejará, añadiendo en elemento con el id content las clases my-6 y p-3

...

export default component$(() => {
...
return <div>
<Navbar />
<div id="content" class="md:container md:mx-auto p-3 my-6">
<Slot />
</div>
</div>;
});

Y su resultado visual será el siguiente:

¿Queréis probar que se adapta bien el contenido verticalmente? ¿Si? Vamos a probarlo con una prueba sencilla y rápida

Añadimos un array de 100 elementos en la página principal (src/routes/index.tsx), creándolo de la siguiente forma:

const myArray = Array.from(Array(100).fill(''), (_, i) => i+1);

Implementando en el componente para que se renderice del 1 al 100 en formato lista (estilos de la lista):

import { component$ } from '@builder.io/qwik';
import type { DocumentHead } from '@builder.io/qwik-city';

export default component$(() => {
const myArray = Array.from(Array(100).fill(""), (_, i) => i + 1);
return (
<>
<h1>Hi 👋</h1>
<p>
Can't wait to see what you build with qwik!
<br />
Happy coding.
</p>
<ul class="list-disc m-4">
{ myArray.map((element) => (<li>{ element }</li>))}
</ul>
</>
);
});

export const head: DocumentHead = {
title: 'Welcome to Qwik',
meta: [
{
name: 'description',
content: 'Qwik site description',
},
],
};

Y como se puede observar, el resultado se adapta perfectamente a nuestro contenedor (se ha hecho scroll):

Con esto ya tenemos el contenedor listo, quitamos el código de estilo para marcar el contenedor quedando así el contenido de src/routes/layout.tsx

import { component$, Slot } from "@builder.io/qwik";
import Navbar from "~/components/core/navbar";

export default component$(() => {
return (
<div>
<Navbar />
<div class="md:container md:mx-auto p-3 my-6">
<Slot />
</div>
</div>
);
});

Fijar el navbar cuando hacemos scroll

Vamos a hacer que en estos casos, cuando tenemos mucho contenido en el contenedor que mediante el scroll perdemos la información del navbar, cosa que seguramente no queramos que ocurra por la importancia que tiene este elemento.

Vamos a aplicarle la propiedad sticky para fijar ese elemento en la parte superior y usaremos esta información de apoyo

import { component$ } from '@builder.io/qwik';
import { Link } from '@builder.io/qwik-city';
import { menuPrincipalData } from '~/constants/menu';

export default component$(() => {
// Añadimos "sticky top-0"
return (
<div class='navbar bg-neutral text-neutral-content sticky top-0'>
....
</div>
);
});

Para terminar con la estructura del layout principal, vamos a formar nuestro footer.

Todo lo trabajado en este apartado lo podemos encontrar a continuación:

https://github.com/Qwik-Spanish/qwik-tailwindcss-daisyui/commit/c33b2859dd240bfc58d9e3fbde125bfb57ae794d

Footer

Una vez que ya hemos completado el apartado del Navbar y el contenedor principal (Usando Slot)donde tendremos el contenido de las páginas cargadas por rutas, nos queda añadir el componente que corresponde al Footer.

Para ello usaré una de las referencias que podéis encontrar en el siguiente enlace:

En el caso de este artículo seleccionaremos la opción más simple, la que corresponde al Footer con la información principal y el copyright:

Copiamos el HTML de ese componente:

Una vez copiado, lo añadimos dentro del componente Footer, que lo crearemos en src/components/core/footer/index.tsx

Aprovecharemos para añadir el año para el copyright usando la clase Date de Javascript y en vez de ACME Industries Ltd, añadiremos un texto que queramos, como el nombre de nuestra marca.

import { component$ } from "@builder.io/qwik";

export default component$(() => (
<footer class="footer footer-center p-4 bg-base-300 text-base-content">
<div>
<p>
Copyright © {new Date().getFullYear()} - All right reserved by Anartz
Mugika Ledo
</p>
</div>
</footer>
));

Ahora que ya tenemos el componente creado, solo falta añadirlo en el layout principal, el que se encuentra en src/routes/layout.tsx.

import { component$, Slot } from "@builder.io/qwik";
import Footer from "~/components/core/footer";
import Navbar from "~/components/core/navbar";

export default component$(() => {
return (
<div>
<Navbar />
<div class="md:container md:mx-auto p-3 my-6">
<Slot />
</div>
<Footer />
</div>
);
});

Guardamos los cambios y debe de verse algo similar a lo que veis a continuación (tendréis que hacer scroll):

Si el color del Footer no os gusta, se puede cambiar la clasebg-base-300 por la correspondiente que queramos usar.

Recordad que antes hemos usado para cambiar lo que correspondía el texto, ahora si queremos cambiar, consultando en la documentación, disponemos del enlace con las variantes de los fondos de color:

Y llegados a este punto, ya tendríamos el esqueleto de una especie de Landing page super básica, con la que podremos profundizar más aplicando nuestros conocimientos de CSS ya que lo que tenemos aquí no se considera algo finalizado.

Conclusión

Se ha creado esta especie de Landing Page para darle contexto al verdadero objetivo del artículo, mostrar como integrar TailwindCSS y la librería de componentes daisyUI en Qwik de una manera muy sencilla.

Lo hemos hecho, paso a paso y teniendo a mano las referencias de lo que íbamos trabajando.

Este punto es importante, cuando vamos a trabajar con algo nuevo (librería, framework, proyecto,…), es fundamental intentar desenvolverse de la mejor manera posible en la documentación oficial, eso hará que podamos avanzar más rápido y más fácil.

Eso si, hay casos en los que la documentación en vez de ayudar, confunden más, pero no es lo normal.

Os dejo el repositorio con todo lo visto con un extra, he añadido contenidos usando los componentes de daisyUI en las diferentes páginas:

Todos los artículos publicados del curso los encontraréis en la siguiente lista que iré actualizando semanalmente y estableciendo el orden natural recomendado:

Qwik paso a paso desde 0 al detalle

23 stories

Presencia en redes sociales

Podéis encontrarme en las siguientes redes.

--

--

Anartz Mugika Ledo🤗

[{#frontend:[#mobile:{#android, #kotlin, #ionic}}, {#web:{#angular, #qwik, #bootstrap}}],{#backend: [{#graphql, #nestjs,#express, #mongodb, #mysql}]}]