https://github.com/hyva-themes/hyva-modules-tailwind-js
Hyvä-themes TailwindCSS utility functions
https://github.com/hyva-themes/hyva-modules-tailwind-js
css-properties design-tokens tailwindcss tailwindcss-v3 tailwindcss-v4
Last synced: 2 months ago
JSON representation
Hyvä-themes TailwindCSS utility functions
- Host: GitHub
- URL: https://github.com/hyva-themes/hyva-modules-tailwind-js
- Owner: hyva-themes
- License: osl-3.0
- Created: 2022-04-15T17:57:48.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2026-03-18T15:06:43.000Z (3 months ago)
- Last Synced: 2026-03-19T05:37:54.238Z (3 months ago)
- Topics: css-properties, design-tokens, tailwindcss, tailwindcss-v3, tailwindcss-v4
- Language: JavaScript
- Homepage: https://hyva.io
- Size: 705 KB
- Stars: 11
- Watchers: 3
- Forks: 9
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: COPYING.txt
- Security: SECURITY.md
Awesome Lists containing this project
README
# Hyvä Themes Tailwind Utilities
[](https://hyva.io)
[](https://github.com/hyva-themes/hyva-modules-tailwind-js/actions)
[](https://www.npmjs.com/package/@hyva-themes/hyva-modules)
[](https://github.com/hyva-themes/hyva-modules-tailwind-js/blob/main/LICENSE.md)
This NPM package is meant to be used with an installation of Hyvä.
If you're not sure what Hyvä is, please check out [hyva.io](https://www.hyva.io/) to learn more.
## Installation
> [!NOTE]
> If you are using Hyvä 1.1.14 or newer, this package is already included in your `package.json` file by default.
You can install `hyva-modules` via `npm` or other Node-based package managers like `pnpm`:
```sh
npm install @hyva-themes/hyva-modules
```
## Usage
This plugin provides multiple helper functions and Node scripts. Some are built for Tailwind CSS v4, and others are kept for backwards compatibility with Tailwind CSS v3.
Below is a list of each of these functions and their use cases.
## Node Commands for Creating CSS for TailwindCSS
This solution makes our code more future-proof since we don't rely on any Tailwind CSS or PostCSS logic.
Making it independent of the bundler or a compiler allows us and you to use it with any stack.
This has been built for Tailwind v4 support,
since Tailwind v4 no longer has a JavaScript configuration and only CSS can be used.
### `hyva-init`
This command creates a `hyva.config.json` in the theme folder next to `package.json`.
This file is used to configure the other `hyva-*` commands.
To run it, use: `npx hyva-init`.
### `hyva-tokens`
This command creates a `generated/hyva-tokens.css` from a design token input.
To run it, use: `npx hyva-tokens`.
By default, this will look for a `design.tokens.json`,
but if you use **Figma**, you can configure it in `hyva.config.json` to use this file instead:
```json
{
"tokens": {
"src": "acme.figma-tokens.json",
"format": "figma"
}
}
```
Since the format of Figma is diffrent, you need to also pass the `format` key with the value `figma`.
If you only need a few simple tokens, you can also create the tokens directly in `hyva.config.json`:
```json
{
"tokens": {
"values": {
"colors": {
"primary": {
"lighter": "oklch(62.3% 0.214 259.815)",
"DEFAULT": "oklch(54.6% 0.245 262.881)",
"darker": "oklch(37.9% 0.146 265.522)"
}
}
}
}
}
```
By default, `generated/hyva-tokens.css` will be created using `@theme` as the CSS selector, which is the Tailwind v4 syntax.
You can change the `cssSelector` to anything you want via `tokens.cssSelector`.
For example, use `:root` for Tailwind v3 compatibility:
```json
{
"tokens": {
"cssSelector": ":root"
}
}
```
You can also customize the dark mode wrapper used for dark tokens with `tokens.mediaDark`.
It accepts either a CSS `@media` rule or a CSS selector, and defaults to `@media (prefers-color-scheme: dark)`.
For example, to use a class-based dark mode strategy:
```json
{
"tokens": {
"mediaDark": ".dark"
}
}
```
After this, you can import this file into your Tailwind CSS like any other CSS file.
### `hyva-sources`
This is the replacement for `mergeTailwindConfig` and `postcssImportHyvaModules` in Tailwind v4 projects.
This command will create a `generated/hyva-source.css` in your project based on the Hyvä-compatible modules.
To run it, use: `npx hyva-sources`.
This uses the same `app/etc/hyva-themes.json` file as `mergeTailwindConfig` and `postcssImportHyvaModules`
and creates a CSS file using the Tailwind v4 syntax for importing and sourcing the module files.
Since this is now handled by this command, we have moved the exclusion of modules to `hyva.config.json`.
Just as with `postcssImportHyvaModules`, you provide a list of modules you want to exclude.
Since we have a bit more freedom, this command is not just for Hyvä-compatible modules.
You can even include extra paths. For example,
you don't need to include the parent theme manually; you can let this command handle that for you.
Here is an example config where you can see the exclude and include options in action:
```json
{
"tailwind": {
"include": [
{ "src": "app/code/Acme/hyva-module" },
{ "src": "vendor/hyva-themes/magento2-default-theme" }
],
"exclude": [
{ "src": "vendor/hyva-themes/magento2-hyva-checkout/src" }
]
}
}
```
If you want to keep a module's `@source` for Tailwind class scanning but skip its CSS imports, add `keepSource: true` to the exclude entry:
```json
{
"tailwind": {
"exclude": [
{ "src": "vendor/hyva-themes/magento2-hyva-checkout/src", "keepSource": true }
]
}
}
```
By default, module CSS files are resolved from the `view/frontend` area. You can change this with `tailwind.area` — for example, to target an admin theme:
```json
{
"tailwind": {
"area": "adminhtml"
}
}
```
By default, external modules from `hyva-themes.json` are automatically included. You can disable this with `tailwind.includeExternalModules: false` to use only the modules listed under `tailwind.include`:
```json
{
"tailwind": {
"includeExternalModules": false,
"include": [
{ "src": "app/code/Acme/HyvaModule" }
]
}
}
```
## CSS Defaults
This package provides several optional CSS modules that offer default styling for common HTML elements.
They are optimized for TailwindCSS v4 and Hyvä Themes and serve as lightweight alternatives to official TailwindCSS plugins.
To use a module, add the corresponding `@import` rule to your stylesheet.
```css
/* Import all modules at once */
@import "@hyva-themes/hyva-modules/css";
```
Alternatively, you can import modules individually as needed.
### Prose
A lightweight, unopinionated alternative to the `@tailwindcss/typography` plugin.
It provides sensible typographic defaults for long-form content (like CMS blocks) without imposing specific colors or a `max-width`.
```css
@import "@hyva-themes/hyva-modules/css/prose.css";
```
### Forms
A minimal alternative to the `@tailwindcss/forms` plugin, providing clean, basic styles for form elements.
```css
@import "@hyva-themes/hyva-modules/css/forms.css";
```
### Fallback
This module restores utility classes from older TailwindCSS versions (v2/v3) that have been removed in v4.
It ensures backward compatibility with older Hyvä compatibility modules and helps prevent compilation errors during upgrades.
```css
@import "@hyva-themes/hyva-modules/css/fallback.css";
```
## Tailwind v3
The following utilities are for **Tailwind v2** and **v3** projects. If you are on Tailwind v4, use `hyva-sources` and `hyva-tokens` instead.
### `mergeTailwindConfig`
This function is used in **Tailwind v2** and **v3** for merging Tailwind configurations from Hyvä-compatible modules into your theme.
To use this module, import `mergeTailwindConfig` into your `tailwind.config.js` and wrap the exported module object in this function:
```js
const { mergeTailwindConfig } = require('@hyva-themes/hyva-modules');
module.exports = mergeTailwindConfig({
// Your theme's Tailwind config here...
});
```
For more information on Tailwind merging,
please read our documentation at [docs.hyva.io](https://docs.hyva.io/hyva-themes/compatibility-modules/tailwind-config-merging.html).
### `postcssImportHyvaModules`
This is complementary to `mergeTailwindConfig`, but for CSS.
To use this module, import `postcssImportHyvaModules` into your `postcss.config.js` and include it in the list of plugins.
> [!IMPORTANT]
> The `hyva-modules` plugin must be placed before the `postcss-import` and `tailwindcss/nesting` plugins.
```js
const { postcssImportHyvaModules } = require('@hyva-themes/hyva-modules');
module.exports = {
plugins: [
postcssImportHyvaModules,
require('postcss-import'),
// ...other PostCSS plugins
],
};
```
For more information on CSS merging,
please read our documentation at [docs.hyva.io](https://docs.hyva.io/hyva-themes/compatibility-modules/tailwind-source-css-merging.html).
### `twVar` and `twProps`
You can opt into CSS variables in your Tailwind configuration using the `twVar` and `twProps` functions.
With `twVar`, you can add a CSS variable to one or more Tailwind CSS tokens. For example:
```js
const { twVar, mergeTailwindConfig } = require('@hyva-themes/hyva-modules');
const colors = require('tailwindcss/colors');
module.exports = mergeTailwindConfig({
theme: {
extend: {
colors: {
primary: {
lighter: twVar('primary-lighter', colors.blue['600']),
DEFAULT: twVar('primary', colors.blue['700']),
darker: twVar('primary-darker', colors.blue['800']),
},
},
},
},
// The rest of your Tailwind config...
});
```
This will render any Tailwind color utility class with the following CSS value:
```css
.bg-primary {
--tw-bg-opacity: 1;
background-color: color-mix(
in srgb,
var(--color-primary, #1d4ed8) calc(var(--tw-bg-opacity) * 100%),
transparent
);
}
```
> The method for handling opacity with all color syntaxes is based on the upcoming Tailwind CSS v4,
> which uses the CSS function `color-mix()` to make this possible.
> We have reused this to make the transition easier in the future.
You can change the value in your CSS or inline on the page with:
```css
:root {
--color-primary: hsl(20 80% 50%);
}
```
If you don't want to set this for each Tailwind CSS token, we also offer the `twProps` function.
This acts as a wrapper and uses the keys as the name for the CSS variable.
For example, if `twProps` wraps `primary > lighter`, it will create the name `--primary-lighter`.
In this example, we can create the same effect as twVar with less effort:
```js
const { twProps, mergeTailwindConfig } = require('@hyva-themes/hyva-modules');
const colors = require('tailwindcss/colors');
module.exports = mergeTailwindConfig({
theme: {
extend: {
colors: twProps({
primary: {
lighter: colors.blue['600'],
DEFAULT: colors.blue['700'],
darker: colors.blue['800'],
},
}),
textColors: {
primary: twProps({
lighter: colors.blue['600'],
DEFAULT: colors.blue['700'],
darker: colors.blue['800'],
}, 'text-primary'),
},
},
},
// The rest of your Tailwind config...
});
```
#### How to apply `twProps` as a wrapper without applying it to all Tailwind CSS tokens
You can use `Object.assign()` to split two groups inside any Tailwind config group (e.g., `colors`),
so only one part gets the variables and the other part is left as is.
Code Sample
```js
const { twProps, mergeTailwindConfig } = require('@hyva-themes/hyva-modules');
const colors = require('tailwindcss/colors');
module.exports = mergeTailwindConfig({
theme: {
extend: {
colors: Object.assign(
twProps({
primary: {
lighter: colors.blue['600'],
DEFAULT: colors.blue['700'],
darker: colors.blue['800'],
},
secondary: {
lighter: colors.blue['100'],
DEFAULT: colors.blue['200'],
darker: colors.blue['300'],
},
}),
{
background: {
lighter: colors.blue['100'],
DEFAULT: colors.blue['200'],
darker: colors.blue['300'],
},
green: colors.emerald,
yellow: colors.amber,
purple: colors.violet,
}
),
},
},
// The rest of your Tailwind config...
});
```
For more information on `twVar` and `twProps`,
please read our documentation at [docs.hyva.io](https://docs.hyva.io/hyva-themes/working-with-tailwindcss/css-variables-plus-tailwindcss.html#method-2-using-the-new-twprops-and-twvar-functions).
### License
This package is licensed under the **Open Software License (OSL 3.0)**.
* **Copyright:** Copyright © 2020-present Hyvä Themes. All rights reserved.
* **License Text (OSL 3.0):** The full text of the OSL 3.0 license can be found in the `LICENSE.txt` file within this package, and is also available online at [http://opensource.org/licenses/osl-3.0.php](http://opensource.org/licenses/osl-3.0.php).