facebook / docusaurus

Easy to maintain open source documentation websites.
https://docusaurus.io
MIT License
56.59k stars 8.5k forks source link

New Tailwind theme #2961

Open jaredpalmer opened 4 years ago

jaredpalmer commented 4 years ago

💥 Proposal

This may be belong in the Infima repo, but I strongly suggest Docusaurus consider Tailwind. Tailwind already solves for theming out of the box. It also gives developers much more freedom. You can still re-implement Infima's core classes with tailwind, so this actually wouldn't need to be a breaking change.

The benefits:

Next Steps

Have you read the Contributing Guidelines on issues?

Yes

slorber commented 4 years ago

Hi,

I'm not very familar with Tailwind yet.

Currently Infima is a css lib with a few postcss. But it also includes some lightweight vanilla JS components

If I understand correctly, you mean we could implement current Infima CSS classes as a Tailwind preset, instead of the existing css/postcss ?

So we would publish that preset and enable users to extend / customize it more easily?


I see the value of Tailwind, and a similar goal of styling co-located to the markup.

Its scope is larger than current Infima:

jaredpalmer commented 4 years ago

Yes you can and should always purge unused tailwind css. Only the classes actually used in the codebase are kept.

kvnxiao commented 3 years ago

Hoping this is helpful information, as I got TailwindCSS v2 to properly work with the PostCSS config that Docusaurus v2 already uses.

I'm using a custom configureWebpack plugin in a file plugins/my-loaders/index.js like so:

module.exports = function (context, options) {
  return {
    name: 'postcss-tailwindcss-loader',
    configureWebpack(config, isServer, utils) {
      return {
        module: {
          rules: [
            {
              test: /\.css$/,
              use: [
                {
                  loader: require.resolve('postcss-loader'),
                  options: {
                    ident: 'postcss',
                    plugins: () => [
                      require('postcss-import'),
                      require('tailwindcss'),
                      require('postcss-preset-env')({
                        autoprefixer: {
                          flexbox: 'no-2009',
                        },
                        stage: 4,
                      }),
                    ],
                  },
                },
              ],
            },
          ],
        },
      }
    },
  }
}

with package.json referencing a local module dependency "my-loaders": "file:plugins/my-loaders", and docusaurus.config.js plugins entry set up as plugins: ['my-loaders'],

And a tailwind.config.js like so:

module.exports = {
  purge: ['./src/**/*.html', './src/**/*.js', './src/**/*.tsx'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

A reference commit summarizing the above info: https://github.com/Discord4J/documentation/commit/20192796254feb1e4229ca1191191031f4d3e065

Note that the PostCSS version in which Docusaurus v2 currently uses is 7.0.XX, while the latest version of PostCSS is 8.0.X and TailwindCSS v2 by default uses PostCSS V8. I had to use a v7 compatibility install of TailwindCSS v2 for this to all work: "tailwindcss": "npm:@tailwindcss/postcss7-compat" in package.json dependencies.

I'm thinking that maybe tailwindcss can be added directly to the https://github.com/facebook/docusaurus/blob/master/packages/docusaurus/src/webpack/utils.ts#L64-L71 plugin block for getStyleLoaders with PurgeCSS configured for first class support. Since tailwindcss has PurgeCSS enabled, users who don't use tailwindcss will never see it or even know because all the tailwindcss related css rules will be removed. And there should be no performance penalties in terms of time spent compiling for users who don't import tailwindcss into their .css files or index.js/index.tsx.


EDIT: With the newer versions of Docusaurus v2 supporting a configurePostCss option in a plugin, the above code snippet should be changed to the following:

module.exports = function (context, options) {
  return {
    name: 'postcss-tailwindcss-loader',
    configurePostCss(postcssOptions) {
      postcssOptions.plugins.push(
        require('postcss-import'),
        require('tailwindcss'),
        require('postcss-preset-env')({
          autoprefixer: {
            flexbox: 'no-2009',
          },
          stage: 4,
        }),
      )
      return postcssOptions
    },
  }
}
slorber commented 3 years ago

Thanks for these infos.

We'll look at this more in depth soon, as we'll work on our theme gallery (https://github.com/facebook/docusaurus/issues/3522) and Tailwind support is part of it

clairefro commented 3 years ago

@kvnxiao I tried your config for tailwind and can't seem to get past this error (looks like it's still looking for postcss 8):

Error: Cannot find module 'postcss-import'

Do you have a working repo I could take a look at?

kvnxiao commented 3 years ago

@clairefro https://github.com/Discord4J/documentation

You will need to install postcss-import

nahtnam commented 3 years ago

@kvnxiao's solution is great! I just want to add an improvement to it. If you add the following to your tailwind.config.js: important: '#tailwind', then it will not affect the docusaurus pages. Then all you need to do is add <div id="tailwind"> around the pages that you want to use tailwind on!

wibed commented 3 years ago

@kvnxiao according to https://github.com/postcss/postcss-import/issues/435 postcss-import@^12 (current ^14) is based on postcss8

also the install guide on tailwindcss does not mention the postcss-import module https://tailwindcss.com/docs/installation#post-css-7-compatibility-build

why did you made it a dependency on your module?

kvnxiao commented 3 years ago

@wibed This is if you want to have build time imports: https://tailwindcss.com/docs/using-with-preprocessors#build-time-imports It's not a requirement but I enabled it in case I take advantage of it. It's also build time processing so it doesn't affect the output size regardless of whether it's included or not. You may remove the require('postcss-import'), clause from the plugin excerpt I listed above previously if you don't want it.

slorber commented 3 years ago

FYI the next release will have a configurePostCss lifecycle, can be useful for Tailwind until we have first-class support https://github.com/facebook/docusaurus/pull/4185

theankurkedia commented 3 years ago

@nahtnam The one with tailwind.config.js: important: '#tailwind' did not prevent default styles for other docusaurus pages. It was still overriding the default html styles. I tried tailwind.config.js: corePlugins: { preflight: false}, important: '#tailwind' and it worked for me.

Romstar commented 3 years ago

FYI the next release will have a configurePostCss lifecycle, can be useful for Tailwind until we have first-class support

4185

Any idea on a timeline for first-class support?

slorber commented 3 years ago

@Romstar no timeline to be defined, as it requires a significant amount of refactoring work to avoid duplicating everything between the themes. It's not a short term priority but more mid-term.

jquense commented 3 years ago

@slorber if someone wanted a tailwind theme now-ish, would you suggest waiting a bit more, or plowing ahead and making their own (knowing the work will be obsoleted eventually). Is it still a mid term goal? It seems like abstracting common logic from themes, is a fairly significant undertaking and likely requires some rethinking of how themes work?

slorber commented 3 years ago

@jquense I think you'd better implement that theme yourself for now, and we may be able to benefit from this third-party implementation once Docusaurus has refactored its theme system.

The goal is to share the same UX across all the official themes, and just have to implement the UI / head / styled components for each theme. We should also try to make it so that theme refactors are less likely to break sites of users that have implemented a custom theme or swizzled a component. I don't like too much the way swizzling works currently, as it creates a quite implicit API surface for which it's hard to be retrocompatible, so yeah it requires a decent amount of work to prepare all that.

The goal is not just to have a Tailwind theme: it's also to make sure that it's easy to maintain, does not break and stays in sync with the classic theme over time.

We have seen what happens to the "bootstrap" theme over time. As there's currently a lot of code duplication, it became unmaintained and a burden and is now in a very bad state. If we have a Tailwind theme, we don't want that to happen.

Romstar commented 3 years ago

@kvnxiao's solution is great! I just want to add an improvement to it. If you add the following to your tailwind.config.js: important: '#tailwind', then it will not affect the docusaurus pages. Then all you need to do is add <div id="tailwind"> around the pages that you want to use tailwind on!

Actually, can you try this: // tailwind.config.js module.exports = { prefix: 'tw-', }

The prefix solved the collision issue for me.

jquense commented 3 years ago

Ok I've started this: https://github.com/jquense/docusaurus-theme-tailwind It's functional though i've not published it on NPM yet. Would appreciate any contributions if folks have em.

slorber commented 3 years ago

Thanks for that @jquense , that already looks great!

Deployed it so that community can see a preview: https://docusaurus-tailwind-theme-test.netlify.app/

(had trouble running 4c build and there's a missing css module in Navbar, but got it running)

As we'd like to make it easier to implement/maintain a theme as part of the beta period, maybe we can work together on this soon.

Currently, implementing a theme requires maintaining too much code that is not really related to the styling. I'd like to move most of it to the theme-common package and only keep the styled components in themes (those with tailwind classes). If you are willing to help to prepare the new theming infra, let me know.

My goal is to have 2 official themes in the Docusaurus repo, mostly for dogfooding as a proof it's sustainable to implement your own theme (if it's not, we'll feel the pain ourselves). Tailwind has now more traction than bootstrap and is probably the best candidate.

jakub-zebrowski commented 3 years ago

Hello, I have a similar problem with tailwind configuration like people before, and unfortunately, the solution from @kvnxiao is not working in the production build in my case. The problem is that we made a component library based on TailwindCSS and we are installing it as deps, so inside my tailwind.config.js in Docusaurus I have to go through the node_modules path to purge it properly like './node_modules/xxx/*-react/dist/*.js', by xxx is our scope. This line in config file plus monorepo Rush setup in repository plus custom tailwind plugin is creating a problem since purge is going through each and every dependency in node_modules and it shouldn't. This is making a crash a heap JS out of memory which someone also made as a separate ticket.

Is it possible to somehow exclude the whole node_modules in purge but the line which I stated will be in use of webpack/postcss config in some ways? I can say that storybook with this tailwind setup is working just fine and purge is not going through all deps and it is also in the same monorepo project.

jquense commented 3 years ago

that is more of a tailwind config question than a docusaurus one. You can use an array of paths to purge content. For libraries there isn't any way to include them expect to manually include it in the purge settings. feel free to upvote: https://github.com/tailwindlabs/tailwindcss/discussions/5208 for better tailwind support

armandopbringas commented 3 years ago

Hi, please, i need support for my case, i´v been following the steps of @kvnxiao but at the end when, in my case, run yarn start i get the next error message in. my browser console: Captura de Pantalla 2021-09-24 a la(s) 11 53 15

y el siguiente en mi terminal: Captura de Pantalla 2021-09-24 a la(s) 11 54 20

so, the message suggest a naming and a format for the object props but i don´t understand why happen this if follow the steps one bye one.

diegoaguilar commented 3 years ago

@jakub-zebrowski we're also having troubles setting docusaurus with a working Tailwind setup.

In addition I'm pretty interested in options to get Tailwind working with storybook.

Would you like to interact to share thoughts and findings on these problems?

jakub-zebrowski commented 3 years ago

@diegoaguilar we didn't have any problems with the storybook. The setup contains tailwind.config.js, postcss.config.js as you can find in Tailwind docs and inside .storybook/main.js in addons we have this


            name: '@storybook/addon-postcss',
            options: {
                postcssLoaderOptions: {
                    postcssOptions: {
                        plugins: {
                            tailwindcss: {},
                            autoprefixer: {},
                        },
                    },
                    implementation: require('postcss'),
                },
            },
        },```
ptrhck commented 2 years ago

Is it possible to style my home page in src/pages/index.js with Tailwind and leave all other docusaurus styling untouched?

Josh-Cena commented 2 years ago

Quite a few have been asking about the status of the Tailwind theme. We are certainly interested in building another theme that utilizes Tailwind CSS as the styling framework, but it's not blocking for the 2.0 release (see #6113), so we will work on it shortly after the GA release, as a minor version.

slorber commented 2 years ago

There's a question that we never asked about what you expect from this Tailwind theme, compared to the existing Classic/Infima theme:

To me, this is 1) or 2), and not 3)

I'm curious to know how much you expect this Tailwind theme to look/behave differently from the classic theme, please tell us

Why do you care about having a Tailwind theme:


Related to https://github.com/facebook/docusaurus/issues/6649#issuecomment-1042770122

jquense commented 2 years ago

I would hope for the same UX and features but don't require the look exactly the same as the infirma based theme.

I primarily want two things from a tailwind theme

Overall I'd be more than happy with either a recreation of the existing classic theme or a sister theme that is more "tailwind" that embraces the tailwind defaults around spacing responsiveness etc.

slorber commented 2 years ago

Thanks @jquense , that's what I expected

Anyone has other good reasons to use Tailwind here?

Airkro commented 2 years ago

Infima bring troubles, maybe tailwindcss can help, or maybe not.

See: https://github.com/facebook/docusaurus/issues/6032

thinkjrs commented 2 years ago

@slorber I appreciate your ask of the community and specifically lean towards 1 and then 2 above, not 3, similar to your thoughts.

I'd love to start building our firm's docs w/Docusaurus but can't until/unless it plays nicely with tailwindcss, which we use to style all of our components, pages, and apps.

Having the tailwindcss theme look and behave similarly to the infima version is probably useful for devs familiar with just one of the frameworks, as a tool to understand the other framework in the context of Docusaurus.

:1st_place_medal: Thanks for the great work on this lib; I'm particularly stoked to see where things go with tailwindcss.

LunaticMuch commented 2 years ago

I can say the same here. Right now my company is looking at docusaurus but the way css are managed is not nice. You can't go with tailwind and align the UX to the rest of the standard if you use the default classic theme. Otherwise you need to build own theme and it's an effort.

aersosi commented 2 years ago

@jquense

Hey there, I would be happy to help. I've seen your last commits in the "docusaurus-theme-tailwind" are monts ago. Of course, I'm interested in using tailwind for my own docusaurus projects. 👯

slorber commented 2 years ago

Note the classic theme is under serious refactorings to create smaller fine-grained and encapsulated components, and move the technical code (non-coupled to Infima) to the @docusaurus/theme-common package.

I'd suggest waiting for these refactorings to be completed before investing too much time in a third-party Tailwind theme. (although we might be able to copy/paste some existing markup when we are ready)

We'll likely also provide some useful tooling so that all themes that want to provide the same layout/UX as the classic theme can stay in sync and keep the same file-system structure, as the main difference should be the UI/CSS, not the component API surface

jquense commented 2 years ago

I am happy to wait it out. it's been to much work to keep it up compared to what i save using it :P

aersosi commented 2 years ago

@slorber Just a quick question out of curiosity. Do you have a timeline for the TW theme, or is it more like "it's done when it's done"?

Kind regards

slorber commented 2 years ago

it's done when it's done

We are continuously extracting technical / non-ui code from the classic theme so that producing a new Tailwind does not lead to a ton of duplication.

Unfortunately, it's hard to estimate. We'll first cleanup the theme to make it easier to customize, release 2.0 asap, and only then start working on this new official Tailwind theme.

And as part of an open-source project, there is also general maintenance work, community PRs and other quality of life improvements to ship so it's hard to dedicate 100% of the efforts to this single project. But it is definitively something that we try to slowly make happen in the background

PoetaKodu commented 2 years ago

I strongly advise making Tailwind optional.

CodeFromAnywhere commented 2 years ago

I don't know if anyone has the same problem, but for me the tailwind installation had lead to the whole site being ugly. After a lot of searching I found that simply disabling preflight solves it because it doesn't change the html defaults.

You can add this in your tailwind.config.json

 corePlugins: {
    preflight: false,
  }
LunaticMuch commented 2 years ago

I don't know if anyone has the same problem, but for me the tailwind installation had lead to the whole site being ugly. After a lot of searching I found that simply disabling preflight solves it because it doesn't change the html defaults.

You can add this in your tailwind.config.json


 corePlugins: {

    preflight: false,

  }

How did you import tailwind?

paularmstrong commented 2 years ago

Is there an umbrella task or list somewhere for the work to extract logic out of the classic theme and into theme-common to help out on making more themes possible?

slorber commented 2 years ago

No umbrella issue but you could look at theme components and see if there is some code that is technical and not really related to theming/styles/CSS. Sometimes it's hard to extract, but there are still a few low-hanging fruits that contributors can help moving ;)

andreipope commented 2 years ago

Hey @slorber ,

We love Docusaurus, and we're building our documentation website on top of it. We're also looking at using Tailwind, so I'm just wondering if you could shed some light on when the Tailwind theme will be available. I understand that you don't have an ETA, but it would be helpful to know whether it'll take weeks, months, or maybe even more. We're not sure if we'd be better off implementing the key features now and wait for the new theme to be ready before we polish the website or if we should just hack our way through the existing codebase and get all the features implemented on top of the existing classic theme. The main concern is that we have to swizzle a large number of components, and this could cause issues when upgrading our version of Docusaurus.

Thank you, Andrei.

slorber commented 2 years ago

Hey, I'm sorry but I have limited bandwidth, only work on Docusaurus 3d/week, also take holidays, have to spend like 50% of my time doing support and answering issues (like this one).

In conclusion, I have not much more than 1d/week to work on ambitious features for Docusaurus, and it's hard for me to tell you how much time it will take considering there are more urgent things to handle such as migrating to React 18, MDX 2.0, ESM, fixing important bugs, DX issues and pending PRs to reviews.

So no, I really can't answer you on when a Tailwind theme will land, nor what decision you should make.

Please assume it will take time, and that you should rather take a decision based on the current state of Docusaurus instead of waiting for official support.

If you really want Docusaurus with Tailwind support today, it remains possible to implement in userland, as @jquense did in his POC above. And doing so will help us: once the time comes, we'll be able to copy your existing JSX+className markup to create the official version. For sure it requires a lot of effort to create it and keep it on par with the existing classic theme, but it is definitively possible.

Note that you can still contribute to our opencollective if you want to give us more bandwidth to implement things faster.

andreipope commented 2 years ago

Hi,

We appreciate you taking the time to answer our question. We just wanted to get more insight into this. Thanks for sharing all the useful information!

Best, Andrei.

gazpachu commented 1 year ago
 corePlugins: {
    preflight: false,
  }

In my team, we prefer to keep the preflight styles but, in order to avoid collisions with Docusaurus styles, we need to load @tailwind base; earlier than the Docusaurus styles.

Unfortunately, if we add @tailwind base; to the top of the src/css/custom.css file, the TW preflight styles load after the Docusaurus styles. That's what causes the issue with the UI getting borked and the need to disable the preflight.

So, is there any other file we could use to load @tailwind base; earlier? I guess not?

@slorber I think one solution would be to make Docusaurus a headless documentation lib. In that way, everyone could choose their preferred CSS architecture to style the UI. Or keep infima for the default CSS architecture but allow users to completely remove it easily.

slorber commented 1 year ago

@slorber I think one solution would be to make Docusaurus a headless documentation lib

That's already the direction we take by moving most client code not related to styling to a @docusaurus/theme-common package, but there's still a lot of work to do to make it happen.

Or keep infima for the default CSS architecture but allow users to completely remove it easily.

It is already possible to implement your own theme, not using Infima. The problem is that you'll have to reimplement many things. The goal of @docusaurus/theme-common is that you'll have to only have to reimplement the things related to styling, and reuse all the things we already worked on for the classic theme (theme config, React hooks, accessibility, i18n, UX...).


I can't help much on the Tailwind side, I don't have much experience using it so far.

jcstein commented 1 year ago

Is it possible to apply styling to only one page? I'm working on this use-case in this PR

KoenRijpstra commented 1 year ago

@gazpachu I found a workaround for loading the preflight before the Docusaurus styles. I disabled preflight in the tailwind.config.js and then Injected the preflight CSS with the injectHtmlTags option:

async function pluginTailwindCSS(context, options) {
  return {
    name: "docusaurus-tailwindcss",
    injectHtmlTags() {
      return {
        headTags: [
          {
            tagName: "link",
            attributes: {
              rel: "stylesheet",
              href: "https://cdn.jsdelivr.net/npm/tailwindcss/dist/preflight.min.css",
            },
          },
        ],
      };
    },
    configurePostCss(postcssOptions) {
      // Appends TailwindCSS and AutoPrefixer.
      postcssOptions.plugins.push(require("tailwindcss"));
      postcssOptions.plugins.push(require("autoprefixer"));
      return postcssOptions;
    },
  };
},
Karkunow commented 1 month ago

Have this one been resolved?

slorber commented 1 month ago

This hasn't been resolved and is not currently being worked on.

I'm currently working on making Docusaurus much faster, notably by adopting Rust tools like Rspack, SWC, and LightningCSS.

For that, we need to get rid of PostCSS, which is currently needed for Tailwind. In v4 with Oxide Tailwind will also adopt LightningCSS (details).

We'll look into adding first-class Tailwind support, and a Tailwind theme, once we both successfully adopt LightningCSS.