{"id":20504335,"url":"https://github.com/Poimen/stencil-tailwind-plugin","last_synced_at":"2025-05-09T07:31:30.479Z","repository":{"id":43342705,"uuid":"378694452","full_name":"Poimen/stencil-tailwind-plugin","owner":"Poimen","description":"Plugin for using tailwindcss with StencilJS","archived":false,"fork":false,"pushed_at":"2023-05-05T14:47:19.000Z","size":1713,"stargazers_count":51,"open_issues_count":8,"forks_count":5,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-11-11T02:38:30.422Z","etag":null,"topics":["postcss","stencil","stenciljs","tailwind","tailwindcss"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/stencil-tailwind-plugin","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Poimen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-20T16:44:25.000Z","updated_at":"2024-08-11T19:01:42.000Z","dependencies_parsed_at":"2024-06-18T16:55:50.593Z","dependency_job_id":"94c55bd4-50b5-4c86-af58-e27f2cd8437a","html_url":"https://github.com/Poimen/stencil-tailwind-plugin","commit_stats":{"total_commits":173,"total_committers":3,"mean_commits":"57.666666666666664","dds":"0.040462427745664775","last_synced_commit":"256529b79c102fb94d192842c16f4512a42eb72d"},"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Fstencil-tailwind-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Fstencil-tailwind-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Fstencil-tailwind-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Poimen%2Fstencil-tailwind-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Poimen","download_url":"https://codeload.github.com/Poimen/stencil-tailwind-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224837651,"owners_count":17378259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["postcss","stencil","stenciljs","tailwind","tailwindcss"],"created_at":"2024-11-15T19:37:20.878Z","updated_at":"2025-05-09T07:31:30.457Z","avatar_url":"https://github.com/Poimen.png","language":"TypeScript","funding_links":[],"categories":["Plugins"],"sub_categories":["Community"],"readme":"# stencil-tailwind-plugin\n\n#\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/poimen/stencil-tailwind-plugin/main-build)\n![npm](https://img.shields.io/npm/v/stencil-tailwind-plugin)\n\nThis package is used to integrate [tailwindcss](https://tailwindcss.com/) and [StencilJS](https://stenciljs.com/). The versions this package supports:\n| Tailwind CSS Version | Package Version |\n| -------------------- | --------------- |\n| v4                   |   v2.x (main)   |\n| v3                   |   v1.x          |\n| v2                   |   v0.x          |\n\nThis plugin is aimed at using the CSS-based tailwind configuration. The setup of the plugin assumes the CSS configuration system is being used. Please refer to the Tailwind documentation on configuration options of Tailwind from CSS. See the [upgrade guide for details](#upgrade-guide-from-v1-to-v2).\n\nFor an example of a basic Stencil integration, see the [example](https://github.com/Poimen/stencil-tailwind-plugin-example).\n\n## Getting started\n\nThis guide assumes that a Stencil project has already been initialized and configured.\n\n### Installation\n\nInstall the necessary dependencies:\n```bash\nnpm install -D stencil-tailwind-plugin tailwindcss @tailwindcss/postcss\n```\n\n### Configuration\n\nIn the Stencil configuration, consume the plugin:\n```ts\n// stencil.config.ts\nimport { Config } from '@stencil/core';\nimport tailwind from 'stencil-tailwind-plugin';\n\nexport const config: Config = {\n  plugins: [\n    tailwind()\n  ],\n  devServer: {\n    reloadStrategy: 'pageReload'\n  }\n};\n```\n\nIn some configurations, the `reloadStrategy` can be left as `hmr` but on occasions new styles are not applied as expected. For more on HMR, see below.\n\nThere are also a number of options that can be given to the plugin:\n\n| Property          | Description                                               | Default      |\n| ----------------- | --------------------------------------------------------- | ------------ |\n| enableDebug       | Enables debugging                                         | `false`        |\n| `tailwindCssPath` | Path to a css file to read for tailwind css configuration. When not specified a default `@import \"tailwindcss\";` is used | `undefined`  |\n| `injectTailwindConfiguration` | Configuration object to be used for tailwind processing | `undefined`   |\n| `stripComments` | Indicate if the comment headers should be stripped as well | `false`   |\n| `minify` | Indicate if the css should be minified by Tailwind | `true`   |\n| `optimise` | Indicate if the css should be optimised by Tailwind (css is not minified) *Note* if `optimise` and `minify` are set, configuration defaults to `minify` | `false`   |\n\nThe default options can be referenced from the plugin as well:\n```ts\n// stencil.config.ts\nimport tailwind, { PluginOptions } from 'stencil-tailwind-plugin';\n\nconst options = {\n  ...PluginOptions.DEFAULT,\n  stripComments: true\n};\n\nexport const config: Config = {\n  // ...\n  plugins: [\n    tailwind(options)\n  ],\n  // ...\n};\n```\n\n### Available Plugins\n\nThere are 3 plugin's available:\n - `tailwind` - the base tailwind style processor\n - `tailwindHMR` - the tailwind Hot Module Reloader\n - `tailwindGlobal` - handling global tailwind styles\n\n### Default configuration\n\nThe plugin has a global option setter, which means configuration can be set globally instead of locally for each plugin type.\n\nThe configuration of the options can be done as such:\n```ts\n// stencil.config.ts\nimport tailwind, { setPluginConfigurationDefaults, tailwindGlobal, tailwindHMR } from 'stencil-tailwind-plugin';\n\nconst options = {\n  stripComments: true\n};\n\nsetPluginConfigurationDefaults(options);\n\nexport const config: Config = {\n  // ...\n  plugins: [\n    tailwindGlobal(),\n    tailwind(),\n    tailwindHMR()\n  ],\n  // ...\n};\n```\n\nAll the plugins that are not provided configuration will receive the configuration from `setPluginConfigurationDefaults`. This does not preclude setting different options per plugin:\n```ts\n// stencil.config.ts\nimport tailwind, { setPluginConfigurationDefaults, tailwindGlobal, tailwindHMR } from 'stencil-tailwind-plugin';\n\nconst opts = {\n  stripComments: true,\n  minify: true\n};\n\nsetPluginConfigurationDefaults(opts);\n\nexport const config: Config = {\n  // ...\n  plugins: [\n    tailwindGlobal(),\n    tailwind(),\n    tailwindHMR({\n      ...opts,\n      minify: false\n    })\n  ],\n  // ...\n};\n```\n\n### Configuration per file\n\nThere can be situations whereby a Tailwind configuration needs to be applied to a specific file/component. This can be accomplished by providing a configuration function rather than a configuration object. In the examples above and object is used, but in this scenario we will configure the plugin with a function:\n```ts\n// stencil.config.ts\nimport tailwind, { TailwindConfig } from 'stencil-tailwind-plugin';\n\nconst twConfigurationFn = (filename: string) =\u003e {\n  if (filename.includes('the-chosen-one.tsx')) {\n    return '@import \"friendly-font-face\"; @import \"taiwindcss\";';\n  }\n  return '@import \"tailwindcss\"';\n};\n\nconst opts = {\n  injectTailwindConfiguration: twConfigurationFn\n};\n\nexport const config: Config = {\n  // ...\n  plugins: [\n    tailwind(opts)\n  ],\n  // ...\n};\n```\n\nIn the above code `injectTailwindConfiguration` is given a callback function to be able to return the Tailwind configuration CSS that'll be used for the file. The argument `filename` is the full path to the component that will be processed by Tailwind processor.\n\n### Note on callback from plugin\n\nThe file being processed will be the raw file for StencilJS compiler. This means the `filename` will contain query parameters as well:\n```\nsome-component.scss?tag=some-component\n```\n\nThe example about merely checks the `includes` option as this negates the use of tags by StencilJS.\n\nIf there are multiple distributions enabled in the StencilJS configuration, then the configuration function will be called multiple times. StencilJS handles each distribution output separately so each time a file is processed per distribution the configuration is required for that distribution. Presently there is no indication of which distribution Stencil is processing so configuration per file per distribution output is not possible.\n\n### Postcss custom configuration\n\nThere are a number of `postcss` plugins that might be wanted when processing the tailwind output specifically. The nature of the stencil build makes it difficult to pass the custom css directly back into the css pipeline building. Hence, the `postcss` configuration can be completely overridden by creating a `postcss` configuration file.\n\nThe plugin uses the default `postcss-load-config` [package](https://github.com/postcss/postcss-load-config). Hence, any the configuration options can be used as a file.\n\nAs an example of a `postcss` configuration that could be used:\n```js\n// postcss.config.js\nmodule.exports = {\n  plugins: [\n    require('postcss-import'),\n    require('tailwindcss'),\n    require('postcss-sort-media-queries'),\n    require('postcss-combine-duplicated-selectors'),\n    require('cssnano')\n  ]\n};\n```\n\nIf the `tailwindcss` plugin is not specified, it is assumed that the plugins should be run _before_ the default tailwind options. The `tailwindcss` plugin options will be overwritten by the tailwind configuration provided by the plugin, hence, the postcss `tailwindcss` is used as a marker for where `tailwindcss` should be used in the `postcss` chain of plugins.\n\n### Configuration with other plugins\n\nIt is important to note that when using `sass` files, that the `sass` Stencil plugin appears before the tailwind plugin. The `sass` plugin needs to process the `sass` files first before the raw `css` is pasted to the tailwind postcss processor. An example configuration could look like:\n```ts\n// stencil.config.ts\nimport { Config } from '@stencil/core';\nimport { sass } from '@stencil/sass';\nimport tailwind from 'stencil-tailwind-plugin';\nimport { inlineSvg } from 'stencil-inline-svg';\n\nexport const config: Config = {\n  outputTargets: [ /* ... */],\n  plugins: [\n    inlineSvg(),\n    sass({\n      includePaths: [\n        /* ... */\n      ]\n    }),\n    tailwind(),\n  ]\n```\n\n### HMR considerations\n\nStencil's compiler does support HMR, however, for inline styles produced by tailwind, another plugin is required in order for the correct dependencies to be mapped to the file watcher. The HMR plugin can be included by:\n```ts\n// stencil.config.ts\nimport { Config } from '@stencil/core';\nimport tailwind, { tailwindHMR } from 'stencil-tailwind-plugin';\nimport tailwindConfig from './tailwind.config';\n\nexport const config: Config = {\n  // ...\n  plugins: [\n    sass(),\n    tailwind(),\n    tailwindHMR(),\n  ],\n};\n```\n\nThe `tailwindHMR` plugin will register all the `tsx` files against the `css` files. This allows Stencil to watch for changes on those `tsx` files and update the `css` accordingly.\n\nThe HMR ability of Stencil and Web Components makes changes difficult, and generally a page reload is required.\n\nUnfortunately, as of `v2.12.0` of the Stencil compiler, this cannot be done as a single plugin and two plugins are required.\n\n## Global styles with `@apply`\n\nWith the new CSS based configuration, usage of `@apply` is discouraged by the Tailwind community.\n\n## Caveat on Function Components (1)\n\nThere are some issues around functional components when they are located in external files to a component. The plugin attempts to insert the Function Component styles into the host component and in so doing, the Stencil HMR does not detect the changes correctly and *will* require a rebuild when this happens.\n\nAs an example, given:\n```tsx\n// component-A.tsx\nimport { FuncComp } from '../common/UtilsFunctionalComponents'\n\n// rest of the normal component that uses \u003cFuncComp /\u003e\n```\nAnd:\n```tsx\n// component-B.tsx\nimport { FuncComp } from '../common/UtilsFunctionalComponents'\n\n// rest of the normal component that uses \u003cFuncComp /\u003e\n```\nAnd:\n```tsx\n// common/UtilsFunctionalComponents.tsx\nexport const FuncComp: FunctionalComponent\u003cFunctionalCompProps\u003e = ({ name }) =\u003e (\n  \u003ch1 class=\"text-indigo-700\"\u003eThis is a functional one - Hello, {name}!\u003c/h1\u003e\n);\n```\n\nIn this example, `component-A` and `component-B` will both contain the style definition for `text-indigo-700` because they both import `FuncComp`.\n\nIf `common/UtilsFunctionalComponents.tsx` is updated, neither `component-A.tsx` or `component-B.tsx` will be build by Stencil's HMR, hence the style class change from `FuncComp` will not reflect.\n\n## Caveat on Function Components (2)\n\nFunctional components can be composed of other functional components. However, there is a known issue where the subsequent functional component (the component that is being used inside the functional component) will not generate any styles. The styles are only generated for the first level of functional components. This is due to the way the Stencil compiler handles stylesheets and functional component building.\n\n## Peer Dependencies\n\nThis plugin requires the following peer dependencies:\n  - @tailwindcss/postcss\n  - tailwindcss\n  - typescript\n\nThese are provided as peer dependencies so consumers can override the versions.\n\n## Development\n\nClone the repo and install the dependencies:\n```bash\npnpm install\n```\n\nRun tests:\n```bash\npnpm tests\n```\n\n## Honourable mentions\n\nA lot of inspiration for this plugin was taken from the similarly named plugin, [stencil-tailwind](https://github.com/jrowlingson/stencil-tailwind) by *Jack Rowlingson*.\n\nInspiration also taken from [proto-stencil-tailwind](https://github.com/eswat2/proto-stencil-tailwind) that moves `stencil-tailwind` forward by *Richard Hess*.\n\nSpecial thanks to the above.\n\n## Other options\n\nFor other ways of integrating Tailwind into your project, [Anthony Giuliano](https://twitter.com/a__giuliano) wrote a blog post:\n\nhttps://ionicframework.com/blog/how-to-integrate-tailwind-css-into-your-stencil-project/\n\n\n## Upgrade Guide from v1 to v2\n\n### Package installs\n\n`v2` uses the postcss plugin for tailwind more directly than `v1`. Install the `@tailwindcss/postcss`:\n```\nnpm install -D @tailwindcss/postcss\n```\n\n### Configuration changes\n\nThe configuration structure has changed for the new Tailwind v4 configuration in CSS.\n\n#### Deprecated options\n - `tailwindCssContents` (see injectTailwindConfiguration)\n - `tailwindConf` (see injectTailwindConfiguration)\n - `useAutoPrefixer` (default Tailwind uses autoprefixer internally)\n - `postcss` (removed)\n\n#### New options\n - `injectTailwindConfiguration` - returns the configuration CSS for tailwind\n - `optimise` - passed to Tailwind to optimise the output without minification. See Tailwind documentation.\n\n### Type changes\n\nThere are numerous type renames. The generally exposed versions are:\n - `PluginConfigOptsDefaults` renamed to `PluginConfigOptionsDefaults`\n - `PluginConfigOpts` renamed to `PluginConfigurationOptions`\n\n### Option Default Updates\n - `PluginOpts` renamed to `PluginOptions`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPoimen%2Fstencil-tailwind-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPoimen%2Fstencil-tailwind-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPoimen%2Fstencil-tailwind-plugin/lists"}