Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Tailwindcss Plugins #32

Closed
sastan opened this issue Dec 29, 2020 · 14 comments
Closed

Support Tailwindcss Plugins #32

sastan opened this issue Dec 29, 2020 · 14 comments
Labels
🛑 Abandoned The issue or Pull Request will not be worked on 💡 Proposal Request for comments 🌬 Tailwind CSS compatibility Some feature of Tailwind CSS is missing or not working as expected

Comments

@sastan
Copy link
Collaborator

sastan commented Dec 29, 2020

Tailwindcss Plugin Documentation

Benefits

Supporting plain tailwindcss plugins would allow users to re-use existing plugins and prevent introducing a new plugin API.

Plugin API

addUtilities(), for registering new utility styles

plugin(function({ addUtilities }) {
  const newUtilities = {
    '.skew-10deg': {
      transform: 'skewY(-10deg)',
    },
    '.skew-15deg': {
      transform: 'skewY(-15deg)',
    },
  }

  addUtilities(newUtilities)
})

We can convert the CSS-in-JS object using twind/css. For each top-level key extract the plugin name and register it's definiton as a twind plugin.

addUtilities() accepts several options. We should discuss if support for these is required for an initial release.

addUtilities(newUtilities, {
  respectPrefix: false,
  respectImportant: false,
  variants: ['responsive', 'hover']
})

To be fully compatible we should support prefix and important configuration settings.

addComponents(), for registering new component styles

Works just like addUtilities() but adds the generated classes into the component layer. We could increase the presedence for these to simulate a component layer.

addBase(), for registering new base styles

This should add the generated classes to the preflight. They should not be hashed or prefixed.

addVariant(), for registering custom variants

Allows you to register your own custom variants that can be used just like the built-in hover, focus, active, etc. variants.

plugin(function({ addVariant, e }) {
  addVariant('disabled', ({ modifySelectors, separator }) => {
    modifySelectors(({ className }) => {
      return `.${e(`disabled${separator}${className}`)}:disabled`
    })
  })
})

e(), for escaping strings meant to be used in class names

Already implemented in util.ts as escape.

prefix(), for manually applying the user's configured prefix to parts of a selector

The prefix function will prefix all classes in a selector and ignore non-classes, so it's totally safe to pass complex selectors like this one

prefix('.btn-blue .w-1\/4 > h1.text-xl + a .bar')
// => '.tw-btn-blue .tw-w-1\/4 > h1.tw-text-xl + a .tw-bar'

theme(), for looking up values in the user's theme configuration

Allow to access the theme. Already implemented within the theme resolver.

variants(), for looking up values in the user's variants configuration

This may be no-op as twind supports all variants for every directive.

config(), for looking up values in the user's Tailwind configuration

Provides access to the default configuration.

postcss, for doing low-level manipulation with PostCSS directly

This may never be available as twind is not using postcss. On accessing the property an error should be thrown.

Registering Plugins

setup must support an array of functions:

setup({
  plugins: [
    plugin(function({ addUtilities, addComponents, e, prefix, config }) {
      // Add your custom styles here
    }),
  ]
})

Challenges

Plugins depend on 'tailwindcss/plugin'

This could be solved setting up the bundler to alias tailwindcss/plugin to twind/plugin. Preact has a good guide how to do that.

Most plugins are written in CJS

Importing plugins may work in bundler environment. But if used directly in the browser this may not work.

Many plugins use lodash (bundle size)

This is not really a challenge but points more to how using plugins could increase the bundle size.

@sastan sastan added pr³ ✨ Feature New Feature 🌬 Tailwind CSS compatibility Some feature of Tailwind CSS is missing or not working as expected labels Dec 29, 2020
@joshua1
Copy link

joshua1 commented Dec 29, 2020

I was about to ask how to use tailwindcss plugins like the ones in tailwindUI (@tailwindcss/forms) , then i saw this. I will await the outcome of this, as i wanted to try using tailwind-UI with twind

@bravo-kernel
Copy link
Contributor

Awesome tool, support for Tailwind UI would be great ❤️

@sastan
Copy link
Collaborator Author

sastan commented Dec 30, 2020

Awesome tool, support for Tailwind UI would be great ❤️

We hope that we can achieve that.

@thelinuxlich
Copy link

Eager to use tailwindcss/forms!

@sastan
Copy link
Collaborator Author

sastan commented Feb 7, 2021

Eager to use tailwindcss/forms!

@thelinuxlich @joshua1 You could try https://github.com/tw-in-js/twind-forms

@sastan
Copy link
Collaborator Author

sastan commented Feb 7, 2021

After thinking about this and porting tailwindlabs some plugins (@twind/forms, @twind/aspect-ratio and @twind/line-clamp) I'm leaning towards a new module which would create a twind configuration from a tailwind config:

import { setup } from 'twind'
import { compat } from 'twind/compat'

setup(
  compat({
    // Tailwind config
    plugins: [
      // List of tailwind plugins
    ]
  })
)

Or even:

import { setup } from 'twind/compat'

setup({
  // Tailwind config
  plugins: [
    // List of tailwind plugins
  ]
})

@ggoodman
Copy link

ggoodman commented Feb 7, 2021

I love the concept! I hope that you consider exposing the mapper.

@jgoux
Copy link

jgoux commented Mar 15, 2021

Hello, how would you adapt https://github.com/stormwarning/tailwindcss-capsize ?

@danielweck
Copy link
Member

Twind's primary developer mentioned a code refactoring in this comment (to align the typography plugin with others, and to hook into the autocompletion VSCode / Typescript extension):

tw-in-js/typography#2 (comment)

So I guess the developer uses some sort of template / scaffolding for creating such plugins. It would be great if a "create" Yarn / NPM utility was available to easily kick-start Twind plugins based on Tailwind ones :)
(this would make it possible for the Twind community to help build extensions to the core library)

@lukejacksonn
Copy link

All plugins are written the same in principle. Whether they are core, supplementary or custom. Furthermore they are all just functions that get called when certain keywords are picked up by the compiler.

See here for docs: https://twind.dev/docs/handbook/advanced/plugins.html#plugins-without-arguments

With regards capsize, the principle is the same, so something like:

import { setup } from 'twind'

setup({
  plugins: {
    'capsize': ([font, size, lineHeight]) => {
       return computeCapsize(font, size, lineHeight);
    },
  },
})

Where computeCapsize returns some CSS-in-JS object with the appropriate values according to their algorithm. Now if the compiler came across capsize-sans-sm-tight then it would go ahead and compute/inject the appropriate rules.

@sastan sastan added 💡 Proposal Request for comments and removed pr³ ✨ Feature New Feature labels Jan 25, 2022
@KyleJune
Copy link

KyleJune commented May 2, 2022

Any updates on the compat API?

If not, what's the manual process of converting a tailwindcss plugin into a twind plugin? I'm new to tailwindcss and twind, but might be able to help with implementing a compatibility layer depending on the size and scope of such a project. If I'm unable, that information might inspire someone else to take on this feature.

Edit: I'm going to just switch to using the latest next release, it has a preset for the tailwindcss forms plugin that should meet my needs.

@sastan
Copy link
Collaborator Author

sastan commented May 5, 2022

Honestly I do not believe it will happen any time soon. For now I try to provide the most common tailwind plugins as presets.

@stale
Copy link

stale bot commented Mar 1, 2023

Hey folks. This issue hasn't received any traction for 90 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it.

@shellscape
Copy link

#490 was opened so this should probably be reopened. I have an interest in seeing this supported for https://jsx.email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🛑 Abandoned The issue or Pull Request will not be worked on 💡 Proposal Request for comments 🌬 Tailwind CSS compatibility Some feature of Tailwind CSS is missing or not working as expected
Projects
None yet
Development

No branches or pull requests

10 participants