question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support Tailwindcss Plugins

See original GitHub issue

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.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:15
  • Comments:12 (4 by maintainers)

github_iconTop GitHub Comments

7reactions
sastancommented, 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
  ]
})
3reactions
sastancommented, Dec 30, 2020

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

We hope that we can achieve that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Plugins - Tailwind CSS
Overview. Plugins let you register new styles for Tailwind to inject into the user's stylesheet using JavaScript instead of CSS. To get started...
Read more >
Plugins - Tailwind CSS
Plugins let you register new styles for Tailwind to inject into the user's stylesheet using JavaScript instead of CSS. To get started with...
Read more >
Writing Plugins - Tailwind CSS
Plugins let you register new styles for Tailwind to inject into the user's stylesheet using JavaScript instead of CSS. To get started with...
Read more >
Editor Setup - Tailwind CSS
Plugins and configuration settings that can improve the developer experience when working with Tailwind CSS.
Read more >
Using with Preprocessors - Tailwind CSS
A guide to using Tailwind with common CSS preprocessors like Sass, Less, and Stylus. Since Tailwind is a PostCSS plugin, there's nothing stopping...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found