daisyui
daisyui copied to clipboard
How to use this with deno + fresh
Hi, how can I use this UI framework with Deno + Fresh + Twind? I tried importing it from https://esm.sh/daisyui and importing it in twind configuration, but it does not work, styles just do not apply.
// utils/twind.ts
import { IS_BROWSER } from "$fresh/runtime.ts";
import { Configuration, setup } from "twind";
export * from "twind";
import daisyui from "daisyui";
export const config: Configuration = {
darkMode: "class",
mode: "silent",
plugins: [daisyui],
};
if (IS_BROWSER) setup(config);
// import_map.json
{
"imports": {
"$fresh/": "https://deno.land/x/[email protected]/",
"preact": "https://esm.sh/[email protected]",
"preact/": "https://esm.sh/[email protected]/",
"preact-render-to-string": "https://esm.sh/[email protected][email protected]",
"@twind": "./utils/twind.ts",
"twind": "https://esm.sh/[email protected]",
"twind/": "https://esm.sh/[email protected]/",
"daisyui": "https://esm.sh/daisyui"
}
}
Looking at the twind repo, it seem like it doesn't support importing tailwind plugins directly.
I would recommend against using twind, as it honestly brings more drawbacks than advantages when you want to extend Tailwind with plugins. Especially since twind's plugins are mostly broken or outdated (already had the fun to deal with twind's typography implementation which doesn't allow overrides).
I'd recommend the approach to set up native Tailwind with the standalone-cli.
Anyway, enough opinions. The fastest way to get daisyUI running is to just import the full stylesheet of daisyUI. Take the following fresh components as an example:
import { Head } from "$fresh/runtime.ts"
import { ComponentChildren } from "preact"
interface Props {
children: ComponentChildren
}
const MainLayout = ({ children }: Props) => {
return <>
<Head>
{/* Tailwind Stylesheet */}
<link rel="stylesheet" href="/styles.css" />
{/* DaisyUI */}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/full.css" rel="stylesheet" type="text/css" />
</Head>
<main>
{children}
</main>
</>
}
export { MainLayout }
Together with the actual route:
import Counter from "../islands/Counter.tsx";
import { MainLayout } from "layouts/MainLayout.tsx";
export default function Home() {
return (
<MainLayout>
<p class="border border-red-500 font-semibold">
Tailwind test with red border.
</p>
<button class="btn btn-outline">This is a daisyUI styled button</button>
<Counter start={3} />
</MainLayout>
);
}
Hey @VIEWVIEWVIEW I am trying to do just that. Can I ask you for some advice? How do you optimise when using the standalone? I ended up running it as a Deno.run()
command, but it looks shabby.
@MarcoSantonastasi I'm not sure what exactly you mean. Please ask again if I understood you wrong.
If you want to run commands concurrently, you can do that by concatenating two commands with &
in your deno.json's task. (You must not use &&
as that would chain execution instead of execute concurrently.
Ex:
{
"tasks": {
"start": "tailwindcss.exe -i input.css -o ./static/styles.css --watch & deno run -A --watch=static/,routes/ dev.ts"
},
}
This will run tailwindcss-cli in background and keep building according to your tailwind.config.js
When you move to production, you probably want to have a small build step if you're not committing the generated /static/styles.css
to source control. In that case, you can copy the ask above and replace &
with &&
.
tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./routes/**/*.{tsx,ts}", "./islands/**/*.{tsx,ts}", "./components/**/*.{tsx,ts}"],
theme: {
extend: {},
},
plugins: [],
}
Here's a small tree how my files a structured.
For brevity, I have removed the clutter like components, routes, imports map etc.:
โ deno.json
โ dev.ts
โ download-tailwind.sh <-- small utility script which downloads the latest tailwindstandalone-cli
โ input.css <-- this is where my tailwind directives are (@tailwind base; @tailwind components; etc)
โ main.ts
โ tailwind.config.js <-- normal tailwind config
โ tailwindcss.exe <-- standalone cli
|
โโโโstatic
favicon.ico
styles.css <-- this is the tailwind output. This file gets referenced with <link rel ... /> in "MainLayout.tsx"
download-tailwind.sh (You can replace it with macOS or Linux binary, depending on what you use)
curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-windows-x64.exe
chmod +x tailwindcss-windows-x64.exe
mv tailwindcss-windows-x64.exe tailwindcss.exe
Hey @VIEWVIEWVIEW thanks for your reply and apologies for my crappy grammar. Let me put my case into context. I am trying to integrate tailwindcss into an SSG called Lume (https://lume.land). Lume has event hooks. I can run a function upon build (what I am doing) or I could theoretically run PostCSS as a ESM module in Deno and tailwind as a PostCSS plugin (the ideal setup). Now, since tailwindcss is not available as a ESM module, it cannot be run as a PostCSS plugin in Deno/Lume, which leaves us with the hook-fired function. Running the function as an event hook forces me to run the tailwind standalone as a system call Deno.run(). The solution has been validated by the Lume.land maintainer as the only possibility. If we accept to run tailwindcss as a stand-alone, I seem to be incapable of running plugins inside tailwind itself. For example, I am unable to mount FlowByte or DaisyUI as UI kits, etc. My folder/file sturcture is almost identical to yours. Here is the snippet fo the sys call in the function:
site.addEventListener("afterBuild", async () => {
const tailwindBin = await getTwBinFullPath(version, dir);
const process = Deno.run({
cmd: [
tailwindBin,
"-i",
"./_site/css/main.css",
"-o",
"./_site/css/main.css",
],
});
await process.status();
process.close();
});
I was hoping you could shed some light on the best way to take advantage of the tailwind ecosystem in Deno (awesome tech, btw...) considering that realistically you would always be inside a framework (Fresh?) or an SSG (Lume?) I hope this is a better wording of my "problem" Thanks!
Take a look here: https://github.com/tailwindlabs/tailwindcss/discussions/5710#discussioncomment-1904271
The solution has been validated by the Lume.land maintainer as the only possibility. If we accept to run tailwindcss as a stand-alone, I seem to be incapable of running plugins inside tailwind itself.
You can actually run plugins with the tailwind-standalone version. I created a demo repository with lume + tailwind + daisyui + @tailwindcss/typography here: https://github.com/VIEWVIEWVIEW/lume-tailwind-daisyui-typography
It's basically the same as I did above: Generate the stylesheet decoupled from the deno process. Using Deno.run
for this is bad practice imo.
You can still use postcss for other postcss-plugins different from tailwind, if you really insist on doing so. Can you check the repo out and tell me if that's actually a solution for you?