Nonostante Tailwind offra un insieme di utility abbastanza ampio, non potrà mai coprire tutte le necessità richieste dai programmatori. Per questa ragione, gli sviluppatori del framework hanno previsto la possibilità di aggiungere nuove funzionalità tramite plugin esterni. Questo ha il duplice vantaggi di creare un insieme di librerie open source da inserire dentro il nostro progetto e di permettere, qualora ci fosse la necessità, di integrare nativamente funzionalità molto specifiche nel progetto al quale stiamo lavorando.
Per sviluppare un plugin, quello che dobbiamo fare è creare un nuovo file Javascript dedicato al plugin ed includerlo all'interno del nostro file di configurazione all'interno della property plugins
, come abbiamo già visto nella seconda lezione di questa guida:
module.exports = {
theme: {
[...]
},
plugins: [
require('./my-tailwind-plugin.js'),
],
};
Esistono 4 diverse tipologie di elementi che possono essere aggiunti al framework tramite plugin. È possibile infatti aggiungere nuove utilities, nuovi componenti, modificare gli stili base e aggiungere variazioni.
Aggiungere nuove utilities
Questa tipologia di plugin permette di creare nuove classi utility che possono essere condivise da diversi progetti creando una dipendenza npm. L'implementazione di un plugin è triviale, basta invocare il metodo addUtilities
fornito direttamente dal modulo plugin presente nel framework.
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addUtilities }) {
const newUtilities = {
'.skew-10deg': {
transform: 'skewY(-10deg)',
},
'.skew-15deg': {
transform: 'skewY(-15deg)',
},
}
addUtilities(newUtilities)
})
]
}
In questo esempio sono state aggiunte due nuove classi, skew-10deg
e skew-15deg
, che agiscono sulla property transform
. Essendo le classi generate da un file Javascript, è possibile sfruttare tutte le funzionalità del linguaggio come cicli o l'inclusione di librerie di terze parti.
Aggiungere nuovi componenti
In Tailwind CSS, un componente è una sorta di alias per identificare un set di regole. Anche in questo caso scrivere un plugin che aggiunga componenti è abbastanza semplice, grazie al metodo addComponents
.
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addComponents }) {
const buttons = {
'.btn': {
padding: '.5rem 1rem',
borderRadius: '.25rem',
fontWeight: '600',
},
}
addComponents(buttons)
})
]
}
In questo caso avremo a disposizione la classe btn
che prevede una serie di regole CSS preimpostate. Questo ovviamente non ci impedirà di mixare questa classe con ulteriori utility presenti nel framework, ma ci offrirà un punto di partenza standard.
Modificare gli stili base
La tipologia di estensione più semplice, ma più impattante, che possiamo implementare è la modifica degli stili base dei tag HTML. Anche in questo caso il framework ci mette a disposizione un metodo atto allo scopo: addBase
.
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addBase, config }) {
addBase({
'h1': { fontSize: config('theme.fontSize.2xl') }
})
})
]
}
In questo caso, sfruttando l'oggetto config per ottenere il valore di un utility, abbiamo modificato il comportamento standard di tutti i tag <h1>
presenti nella nostra applicazione.
Aggiungere variazioni
La tipologia di intervento sicuramente più complessa da implementare è l'aggiunta di una variazione. Secondo la documentazione ufficiale, possono esistere due tipologie di variazioni: quelle basic, implementate direttamente tramite selettori CSS, e quelle più complesse che richiedono lavoro ulteriore da parte dello sviluppatore.
Implementare le variazioni basic è simile alle altre tipologie di estensioni che abbiamo precedentemente applicato al framework. Grazie al metodo addVariant
possiamo facilmente aggiungere una variazione in questo modo:
const plugin = require('tailwindcss/plugin')
module.exports = {
plugins: [
plugin(function({ addVariant, e }) {
addVariant('first-child', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`first-child${separator}${className}`)}:first-child`
})
})
})
]
}
In questo caso è stata creata la variazione first-child
che non fa altro che sfruttare la pseudo classe CSS per implementare questo comportamento.
Se volessimo invece spingerci più in là, potremmo sfruttare l'oggetto container
messo a disposizione sempre dal metodo addVariant
ma molto più complesso del precedente metodo modifySelector
. Questo particolare oggetto fa parte delle API esposte da Post CSS, libreria di basso livello per manipolare file CSS. Considerando la tipologia di intervento molto particolare e in parte out-of-scope rispetto a TailwindCSS, lasciamo opzionale l'approfondimento per il lettore particolarmente interessato alla questione.