{"id":15960512,"url":"https://github.com/kenoxa/beamwind","last_synced_at":"2025-03-16T07:31:51.722Z","repository":{"id":55634743,"uuid":"315976787","full_name":"kenoxa/beamwind","owner":"kenoxa","description":"a collection of packages to compile Tailwind CSS like shorthand syntax into CSS at runtime","archived":false,"fork":false,"pushed_at":"2020-12-16T13:05:46.000Z","size":2017,"stargazers_count":50,"open_issues_count":1,"forks_count":4,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-03-08T06:28:51.250Z","etag":null,"topics":["css","css-framework","css-in-js","functional-css","responsive","tailwindcss","utility-classes"],"latest_commit_sha":null,"homepage":"https://beamwind.js.org","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/kenoxa.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}},"created_at":"2020-11-25T15:17:02.000Z","updated_at":"2024-12-09T00:28:50.000Z","dependencies_parsed_at":"2022-08-15T05:01:03.837Z","dependency_job_id":null,"html_url":"https://github.com/kenoxa/beamwind","commit_stats":null,"previous_names":[],"tags_count":98,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenoxa%2Fbeamwind","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenoxa%2Fbeamwind/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenoxa%2Fbeamwind/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kenoxa%2Fbeamwind/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kenoxa","download_url":"https://codeload.github.com/kenoxa/beamwind/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243806035,"owners_count":20350775,"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":["css","css-framework","css-in-js","functional-css","responsive","tailwindcss","utility-classes"],"created_at":"2024-10-07T15:04:02.421Z","updated_at":"2025-03-16T07:31:51.039Z","avatar_url":"https://github.com/kenoxa.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Beamwind\n\n\u003e a [collection of packages](#packages) to compile [Tailwind CSS] like shorthand syntax into CSS at runtime\n\n[![MIT License](https://badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE)\n[![Latest Release](https://flat.badgen.net/npm/v/@beamwind/core?icon=npm\u0026label)](https://www.npmjs.com/package/@beamwind/core)\n[![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/core?icon=packagephobia\u0026label\u0026color=blue)](https://bundlephobia.com/result?p=@beamwind/core)\n[![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github\u0026label)](https://github.com/kenoxa/beamwind)\n[![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript\u0026label)](https://unpkg.com/browse/@beamwind/core/types/core.d.ts)\n[![CI](https://github.com/kenoxa/beamwind/workflows/CI/badge.svg)](https://github.com/kenoxa/beamwind/actions?query=workflow%3Aci)\n[![Coverage Status](https://flat.badgen.net/coveralls/c/github/kenoxa/beamwind/main?icon=codecov\u0026label)](https://coveralls.io/github/kenoxa/beamwind?branch=main)\n[![PRs Welcome](https://flat.badgen.net/badge/PRs/welcome/purple)](http://makeapullrequest.com)\n\n\u003e [Read the docs](https://beamwind.js.org) |\n\u003e [API](https://beamwind.js.org/packages/beamwind) |\n\u003e [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/core/CHANGELOG.md) |\n\u003e [⚡️ Demo](https://esm.codes/#Ly8gQmVhbXdpbmQgZGVtbyAoYmFzZWQgb24gY29kZSBieSBAbHVrZWphY2tzb25uIC0gY3JlYXRvciBvZiBvY2VhbndpbmQpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKaW1wb3J0IHsgcmVuZGVyLCBodG1sIH0gZnJvbSAnaHR0cHM6Ly9ucG0ucmV2ZXJzZWh0dHAuY29tL3ByZWFjdCxwcmVhY3QvaG9va3MsaHRtL3ByZWFjdCc7CmltcG9ydCB7IGJ3IH0gZnJvbSAnaHR0cHM6Ly91bnBrZy5jb20vYmVhbXdpbmQ/bW9kdWxlJwoKCmNvbnN0IHN0eWxlID0gewogIC8vIEV4YW1wbGUgb2YgYWJzdHJhY3RlZCBzdHlsZQogIGNvbnRhaW5lcjogYndgaC1mdWxsIGJnLXBpbmstNzAwIHRleHQtd2hpdGUgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJgCn0KCnJlbmRlcigKICBodG1sYAogICAgPGRpdiBjbGFzcz0ke3N0eWxlLmNvbnRhaW5lcn0+CiAgICAgIDxoMSBjbGFzcz0kewogICAgICAgIC8vIEV4YW1wbGUgb2YgYW4gaW5saW5lIHN0eWxlCiAgICAgICAgYndgCiAgICAgICAgICB0ZXh0KDR4bCB1bmRlcmxpbmUpCiAgICAgICAgICBmb250KGJvbGQgc2FucykKICAgICAgICAgIHRyYW5zaXRpb24KICAgICAgICAgIGhvdmVyOih0cmFuc2Zvcm0gcm90YXRlLTYgc2NhbGUtMTI1IGN1cnNvci1wb2ludGVyKQogICAgICAgICAgYWN0aXZlOih0cmFuc2Zvcm0gLXJvdGF0ZS0xMiBzY2FsZS0xNTApCiAgICAgICAgYAogICAgICB9PkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGAsCiAgZG9jdW1lbnQuYm9keQopOw==)\n\n---\n\nThis library takes inspiration from [Tailwind CSS] ([see differences](#tailwind-differences)), [Oceanwind] ([see differences](#oceanwind-differences)) and [Otion] to provide means of efficiently generating mostly atomic styles from shorthand syntax and appending them to the DOM at runtime.\n\n[beamwind](https://github.com/kenoxa/beamwind/blob/main/packages/beamwind) uses the [tailwind default theme](https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/defaultConfig.stub.js) ([@beamwind/preset-tailwind](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind)) and an opinionated set of base styles for modern browsers based on [Tailwind Preflight](https://tailwindcss.com/docs/preflight)\n([@beamwind/preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight)):\n\n```js\nimport { bw } from 'beamwind'\n\ndocument.body.className = bw`h-full bg-pink-700 rotate-3 scale-95`\n```\n\n\u003e ⚡️ Check out the [live and interactive demo](https://esm.codes/#Ly8gQmVhbXdpbmQgZGVtbyAoYmFzZWQgb24gY29kZSBieSBAbHVrZWphY2tzb25uIC0gY3JlYXRvciBvZiBvY2VhbndpbmQpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKaW1wb3J0IHsgcmVuZGVyLCBodG1sIH0gZnJvbSAnaHR0cHM6Ly9ucG0ucmV2ZXJzZWh0dHAuY29tL3ByZWFjdCxwcmVhY3QvaG9va3MsaHRtL3ByZWFjdCc7CmltcG9ydCB7IGJ3IH0gZnJvbSAnaHR0cHM6Ly91bnBrZy5jb20vYmVhbXdpbmQ/bW9kdWxlJwoKCmNvbnN0IHN0eWxlID0gewogIC8vIEV4YW1wbGUgb2YgYWJzdHJhY3RlZCBzdHlsZQogIGNvbnRhaW5lcjogYndgaC1mdWxsIGJnLXBpbmstNzAwIHRleHQtd2hpdGUgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJgCn0KCnJlbmRlcigKICBodG1sYAogICAgPGRpdiBjbGFzcz0ke3N0eWxlLmNvbnRhaW5lcn0+CiAgICAgIDxoMSBjbGFzcz0kewogICAgICAgIC8vIEV4YW1wbGUgb2YgYW4gaW5saW5lIHN0eWxlCiAgICAgICAgYndgCiAgICAgICAgICB0ZXh0KDR4bCB1bmRlcmxpbmUpCiAgICAgICAgICBmb250KGJvbGQgc2FucykKICAgICAgICAgIHRyYW5zaXRpb24KICAgICAgICAgIGhvdmVyOih0cmFuc2Zvcm0gcm90YXRlLTYgc2NhbGUtMTI1IGN1cnNvci1wb2ludGVyKQogICAgICAgICAgYWN0aXZlOih0cmFuc2Zvcm0gLXJvdGF0ZS0xMiBzY2FsZS0xNTApCiAgICAgICAgYAogICAgICB9PkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGAsCiAgZG9jdW1lbnQuYm9keQopOw==)\n\nAs an alternative [@beamwind/system](https://github.com/kenoxa/beamwind/blob/main/packages/system) is a good start if you prefer a semantic naming scheme in your design system: [⚡️ Demo](https://esm.codes/#Ly8gQmVhbXdpbmQgZGVtbyAoYmFzZWQgb24gY29kZSBieSBAbHVrZWphY2tzb25uIC0gY3JlYXRvciBvZiBvY2VhbndpbmQpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKaW1wb3J0IHsgcmVuZGVyLCBodG1sIH0gZnJvbSAnaHR0cHM6Ly9ucG0ucmV2ZXJzZWh0dHAuY29tL3ByZWFjdCxwcmVhY3QvaG9va3MsaHRtL3ByZWFjdCc7CmltcG9ydCB7IGJ3IH0gZnJvbSAnaHR0cHM6Ly91bnBrZy5jb20vQGJlYW13aW5kL3BsYXk/bW9kdWxlJwoKY29uc3Qgc3R5bGUgPSB7CiAgLy8gRXhhbXBsZSBvZiBhYnN0cmFjdGVkIHN0eWxlCiAgY29udGFpbmVyOiBid2BoLWZ1bGwgYmctcHJvbW90ZSBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlcmAKfQoKcmVuZGVyKAogIGh0bWxgCiAgICA8ZGl2IGNsYXNzPSR7c3R5bGUuY29udGFpbmVyfT4KICAgICAgPGgxIGNsYXNzPSR7CiAgICAgICAgLy8gRXhhbXBsZSBvZiBhbiBpbmxpbmUgc3R5bGUKICAgICAgICBid2AKICAgICAgICAgIHRleHQoNHhsIHVuZGVybGluZSkKICAgICAgICAgIGZvbnQoYm9sZCBzYW5zKQogICAgICAgICAgdHJhbnNpdGlvbgogICAgICAgICAgaG92ZXI6KHRyYW5zZm9ybSByb3RhdGUtbWQgc2NhbGUtMnhsIGN1cnNvci1wb2ludGVyKQogICAgICAgICAgYWN0aXZlOih0cmFuc2Zvcm0gLXJvdGF0ZS14bCBzY2FsZS0zeGwpCiAgICAgICAgYAogICAgICB9PkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGAsCiAgZG9jdW1lbnQuYm9keQopOw==)\n\nFor rapid prototyping [@beamwind/play](https://github.com/kenoxa/beamwind/blob/main/packages/play) is the right choice. It combines [@beamwind/preset-tailwind](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) and [@beamwind/preset-system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) with [auto-conversion of unknown theme values](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play): [⚡️ Demo](https://esm.codes/#Ly8gQmVhbXdpbmQgZGVtbyAoYmFzZWQgb24gY29kZSBieSBAbHVrZWphY2tzb25uIC0gY3JlYXRvciBvZiBvY2VhbndpbmQpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKaW1wb3J0IHsgcmVuZGVyLCBodG1sIH0gZnJvbSAnaHR0cHM6Ly9ucG0ucmV2ZXJzZWh0dHAuY29tL3ByZWFjdCxwcmVhY3QvaG9va3MsaHRtL3ByZWFjdCc7CmltcG9ydCB7IGJ3IH0gZnJvbSAnaHR0cHM6Ly91bnBrZy5jb20vQGJlYW13aW5kL3BsYXk/bW9kdWxlJwoKLy8gVGFpbHdpbmQgYW5kIFN5c3RlbSB0aGVtZSB2YWx1ZXMgYXJlIGF2YWlsYWJsZQoKY29uc3Qgc3R5bGUgPSB7CiAgLy8gRXhhbXBsZSBvZiBhYnN0cmFjdGVkIHN0eWxlCiAgY29udGFpbmVyOiBid2BoLWZ1bGwgYmctI0RCMjc3NyB0ZXh0LSNFNUU3RUIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJgCn0KCnJlbmRlcigKICBodG1sYAogICAgPGRpdiBjbGFzcz0ke3N0eWxlLmNvbnRhaW5lcn0+CiAgICAgIDxoMSBjbGFzcz0kewogICAgICAgIC8vIEV4YW1wbGUgb2YgYW4gaW5saW5lIHN0eWxlCiAgICAgICAgYndgCiAgICAgICAgICB0ZXh0KDIuNXJlbSB1bmRlcmxpbmUpCiAgICAgICAgICBmb250KGJvbGQgc2FucykKICAgICAgICAgIHRyYW5zaXRpb24KICAgICAgICAgIGhvdmVyOih0cmFuc2Zvcm0gcm90YXRlLTcgc2NhbGUtMTM1IGN1cnNvci1wb2ludGVyKQogICAgICAgICAgYWN0aXZlOih0cmFuc2Zvcm0gLXJvdGF0ZS0yMyBzY2FsZS0xNzUpCiAgICAgICAgYAogICAgICB9PkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGAsCiAgZG9jdW1lbnQuYm9keQopOw==)\n\n---\n\n\u003cdetails\u003e\u003csummary\u003eTable Of Contents (click to expand)\u003c/summary\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Key Features](#key-features)\n- [Backstory](#backstory)\n- [Usage](#usage)\n- [Packages](#packages)\n- [Theming](#theming)\n- [Dark Mode](#dark-mode)\n- [Plugins](#plugins)\n- [Configuration](#configuration)\n- [Selector Ordering](#selector-ordering)\n- [Roadmap](#roadmap)\n- [Tailwind Differences](#tailwind-differences)\n- [Oceanwind Differences](#oceanwind-differences)\n- [Browser Support](#browser-support)\n- [Acknowledgements](#acknowledgements)\n- [Contribute](#contribute)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c/details\u003e\n\n## Key Features\n\n- 📖 Supports the [vast majority](#missing-features) of Tailwind directives outlined [in the docs](https://tailwindcss.com/docs) ([see differences](#tailwind-differences))\n- 🗜 Is smaller than the average purged css file output from the Tailwind compiler\n- 🚀 Runtime generation of used styles without a build step or purging\n- 💡 [Variant](#variant-grouping) and [Directive](#directive-grouping) grouping to reduce the overwhelming maze Tailwind sometimes creates\n- 🧱 [Extendable with plugins](#plugins)\n- 💅 [Customizable themeing](#theming)\n- 🍱 [Reliable selector ordering](#selector-ordering)\n- ⏱ [Performant runtime characteristics](https://github.com/kenoxa/beamwind/blob/main/benchmarks)\n- 💫 Works without a framework - eg framework agnostic\n- ⚠️ [Warns the developer](#catching-errors) when a unrecognized directive is used\n\n\u003e **Beamwind**: a wind blowing against a vessel from a direction at right angles to its keel for optimal speed\n\n## Backstory\n\nDesign systems embrace a component-oriented mindset. Inspired by [Tailwind CSS], utility classes provide reusable styles with no unwanted side-effects. However, they have to be generated upfront.\n\nAtomicity generalizes the former concept by instantiating style rules on demand. Serving as a solid foundation for constraint-based layouts, [atomic CSS-in-JS](https://sebastienlorber.com/atomic-css-in-js) has come to fluorish at scale.\n\n## Usage\n\n\u003e The following code examples will use [beamwind](https://github.com/kenoxa/beamwind/blob/main/package/beamwind).\n\u003e But the API is the same for [all packages](#packages).\n\nTo use the library, first import the module then invoke the `bw` export using tagged template syntax ([or one of the many other ways](#function-signature)):\n\n```js\nimport { bw } from 'beamwind'\n\ndocument.body.className = bw`h-full bg-purple-500 rotate-3 scale-95`\n```\n\nRunning the above code will result in the following happening:\n\n1. Parse directives (`h-full`, `bg-purple-500`, `rotate-3`, `scale-95`)\n2. Translate directives into CSS rules using [plugins](#plugins) (e.g. `h-full -\u003e { height: 100vh }`).\n3. Inject each CSS rule with a unique class name into a library-managed style sheet\n4. Return a space-separated string of class names\n\n\u003e If you are unfamiliar with the [Tailwind CSS] shorthand syntax please read the [Tailwind documentation](https://tailwindcss.com/docs) about [Utility-First](https://tailwindcss.com/docs/utility-first), [Responsive Design](https://tailwindcss.com/docs/responsive-design) and [Hover, Focus, \u0026 Other States](https://tailwindcss.com/docs/hover-focus-and-other-states).\n\n### Variant Grouping\n\nDirectives with the same variants can be grouped using parenthesis. Beamwind will expand the nested directives; applying the variant to each directive in the group before translation. For example:\n\n\u003e Notice any directives within tagged template literals can span multiple lines\n\n```js\nbw`\n  sm:hover:(\n    bg-black\n    text-white\n  )\n  md:(bg-white hover:text-black)\n`\n// =\u003e sm:hover:bg-black sm:hover:text-white md:bg-white md:hover:text-black\n```\n\nIt is possible to nest groupings too, for example:\n\n```js\nbw`\n  sm:(\n    bg-black\n    text-white\n    hover:(bg-white text-black)\n  )\n`\n// =\u003e sm:hover:bg-black sm:hover:text-white sm:hover:bg-white sm:hover:text-black\n```\n\nObject values which are String, Array or Object start a new variant group:\n\n```js\nbw({\n  sm: {\n    'bg-black': true,\n    'text-white': true,\n    hover: 'bg-white text-black',\n  },\n})\n// =\u003e sm:hover:bg-black sm:hover:text-white sm:hover:bg-white sm:hover:text-black\n```\n\n\u003e Two things to note here is that the outermost variant should always be a responsive variant (just like in tailwind `hover:sm:` is not supported) and that nesting responsive variants doesn't make sense either, for example `sm:md:` is not supported.\n\n### Directive Grouping\n\nDirectives with the same prefix can be grouped using parenthesis. Beamwind will expand the nested directives; applying the prefix to each directive in the group before translation. For example:\n\n```js\nbw`text(center bold gray-500)`)\n// =\u003e text-center text-bold text-gray-500\n\nbw`divide(y-2 blue-500 opacity(75 md:50))`\n// =\u003e divide-y-2 divide-blue-500 divide-opacity-75 md:divide-opacity-50\n\nbw`w(1/2 sm:1/3 lg:1/6) p-2`\n// =\u003e w-1/2 sm:w-1/3 lg:w-1/6 p-2\n```\n\nSome directives like [ring](https://tailwindcss.com/docs/ring-width) need to be applied as is. For that case you can use the special `\u0026` directive which is replaced with the current prefix:\n\n```js\nbw`ring(\u0026 ping-700 offset(4 ping-200))`)\n// =\u003e ring ring-ping-700 ring-offset-4 ring-offset-on-ping-200\n```\n\nNegated values can be used within the braces and will be applied to the directive:\n\n```js\nbw`rotate(-3 hover:6 md:(3 hover:-6))`\n// =\u003e -rotate-3 hover:rotate-6 md:rotate-3 md:hover:-rotate-6\"\n```\n\n### Function Signature\n\nIt is possible to invoke beamwind in a multitude of different ways. The [`bw` function](https://beamwind.js.org/packages/types/interfaces/instance.html#bw) can take **_any_** number of arguments, each of which can be an Object, Array, Boolean, Number, String or [inline plugins](#inline-plugins). This feature is based on [clsx](https://www.npmjs.com/package/cslx).\n\n\u003e **Important**: _Any_ falsey values are discarded!\n\u003e Standalone Boolean and Number values are discarded as well.\n\nFor example:\n\n```js\n// Tag Template Literal (falsey interpolations will be omitted)\nbw`bg-gray-200 rounded`\n//=\u003e 'bg-gray-200 rounded'\n\nbw`bg-gray-200 ${false \u0026\u0026 'rounded'}`\n//=\u003e 'bg-gray-200'\n\nbw`bg-gray-200 ${[false \u0026\u0026 'rounded', 'block']}`\n//=\u003e 'bg-gray-200 block'\n\nbw`bg-gray-200 ${{ rounded: false, underline: isTrue() }}`\n//=\u003e 'bg-gray-200 underline'\n\n// Strings (variadic)\nbw('bg-gray-200', true \u0026\u0026 'rounded', 'underline')\n//=\u003e 'bg-gray-200 rounded underline'\n\n// Objects (keys with falsey values will be omitted)\nbw({ 'bg-gray-200': true, rounded: false, underline: isTrue() })\n//=\u003e 'bg-gray-200 underline'\n\n// Objects (variadic)\nbw({ 'bg-gray-200': true }, { rounded: false }, null, { underline: true })\n//=\u003e 'bg-gray-200 underline'\n\n// Arrays (falsey items will be omitted)\nbw(['bg-gray-200', 0, false, 'rounded'])\n//=\u003e 'bg-gray-200 rounded'\n\n// Arrays (variadic)\nbw(['bg-gray-200'], ['', 0, false, 'rounded'], [['underline', [['text-lg'], 'block']]])\n//=\u003e 'bg-gray-200 rounded underline text-lg block'\n\n// Kitchen sink (with nest\nbw(\n  'bg-gray-200',\n  [1 \u0026\u0026 'rounded', { underline: false, 'text-secondary': null }, ['text-lg', ['shadow-lg']]],\n  'uppercase',\n)\n//=\u003e 'bg-gray-200 rounded text-lg shadow-lg uppercase'\n```\n\n\u003e For advanced use cases `bw` additionally accepts [inline plugins](#inline-plugins).\n\n### Directive Factories\n\nOften you will find yourself in a position to need an abstraction to simplify the creation of directives. A best practice is to create a function that returns the required directives:\n\n```js\nconst btn = (color) =\u003e {\n  if (color) {\n    return `bg-${color} hover:bg-${color}-hover active:bg-${color}-active`\n  }\n\n  return 'inline-block font-bold py-2 px-4 rounded'\n}\n\nbw(btn())\n// =\u003e inline-block font-bold py-2 px-4 rounded\n\nbw([btn(), btn('primary')])\n// =\u003e inline-block font-bold py-2 px-4 rounded bg-primary hover:bg-primary-hover active:bg-primary-active\n```\n\n\u003e This can be converted into a [component plugin](#adding-new-components).\n\n### Extending the default theme\n\n\u003e The [Theming section](#theming) provides detailed insight into the theming options.\n\nImporting and invoking `bw` directly will cause it to use the default theme of that package. To customize the theme, use the [`setup` export](https://beamwind.js.org/packages/types/interfaces/instance.html#setup). This will change the theme used by the `bw` export.\n\n```js\nimport { bw, setup } from 'beamwind'\n\nsetup({\n  theme: {\n    extend: {\n      colors: {\n        'red-500': '#DC2626',\n      },\n    },\n  },\n})\n\nbw`bg-red-500` // will result in a #DC2626 background-color\n```\n\n\u003e `setup` can be called multiple times where each call extends the existing configuration.\n\nAlternatively you can [create a own instance](#instance-creation):\n\n```js\nimport { createInstance } from 'beamwind'\n\nconst cx = createInstance({\n  theme: {\n    extend: {\n      colors: {\n        'red-500': '#DC2626',\n      },\n    },\n  },\n})\n\ncx`bg-red-500` // will result in a #DC2626 background-color\n```\n\n## Packages\n\n\u003e ready to use [instances](#instance-creation)\n\n- [beamwind](https://github.com/kenoxa/beamwind/blob/main/packages/beamwind) - using the [tailwind default theme](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) and [preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight)\n- [@beamwind/system](https://github.com/kenoxa/beamwind/blob/main/packages/system) - using a [semantic design system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) and [preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight)\n- [@beamwind/play](https://github.com/kenoxa/beamwind/blob/main/packages/play) - combining the [tailwind default theme](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind), the [semantic design system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) and [preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight) with [auto-conversion of unknown theme values](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play)\n\n\u003e These packages all use [@beamwind/core](https://github.com/kenoxa/beamwind/blob/main/packages/core) under the hood which only has a minimal theme intended to be used as base to be further configured.\n\nThe [Instance Creation](#instance-creation) section show how to implement your own packages.\n\n### Presets\n\n\u003e reusable configuration presets to create your own [instance](#instance-creation)\n\n- [@beamwind/preset-tailwind](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) - mirroring tailwind default theme\n- [@beamwind/preset-system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) - a semantic design system\n- [@beamwind/preset-play](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play) - auto-conversion of unknown theme values\n\n### Base Styles\n\n\u003e opinionated base styles that are designed to smooth over cross-browser inconsistencies and make it easier to work within the constraints of your design system.\n\n- [@beamwind/preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight) - for modern browsers\n- [@beamwind/reset](https://github.com/kenoxa/beamwind/blob/main/packages/reset) - for legacy browsers like IE10/11\n\n### Helpers\n\n- [@beamwind/colors](https://github.com/kenoxa/beamwind/blob/main/packages/colors) - color utilities\n\n### Examples\n\n- [svelte](https://github.com/kenoxa/beamwind/blob/main/examples/svelte) - using [svelte](https://svelte.dev/)\n\n## Theming\n\n\u003e Customizing the default theme for your project.\n\nThe `theme` property of the `setup` options follows [Tailwinds Theme Configuration](https://tailwindcss.com/docs/theme) It contains keys for `screens`, `colors`, and `spacing`, as well as a key for each customizable core plugin. The [core theme](https://github.com/kenoxa/beamwind/blob/main/packages/core/src/theme.js) is bare bones as most projects have their own colors, sizes, ... and naming system. A tailwind like theme is available via [@beamwind/preset-tailwind](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind). For a full featured design system take a look at [@beamwind/preset-system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system).\n\n\u003e [API / Themes](https://beamwind.js.org/packages/types/interfaces/theme.html) provides an overview of all possible values and differences are highlighted [here](#tailwind-differences).\n\nTo customize the theme call `setup` with a `theme` property:\n\n```js\nimport { setup } from 'beamwind'\n\nsetup({\n  theme: {\n    /* ... */\n  },\n})\n```\n\nIf the new theme needs to access the existing theme a function can be used:\n\n```js\nsetup({\n  theme: (theme) =\u003e {\n    return {\n      extend: {\n        colors: {\n          important: theme('colors', 'critical'),\n        },\n      },\n    }\n  },\n})\n```\n\n### Referencing other values\n\nIf you need to reference another value in your theme, you can do so by providing a closure instead of a static value. The closure will receive a [`theme()`](https://beamwind.js.org/packages/types/interfaces/themeresolver.html) function that you can use to look up other values in your theme.\n\n```js\nsetup({\n  theme: {\n    colors: {\n      important: (theme) =\u003e theme('colors', 'critical', 'red' /* Fallback */),\n    },\n    fill: (theme) =\u003e theme('colors'),\n  },\n})\n```\n\n### Colors\n\nThe `colors` key allows you to customize the global color palette for your project.\n\nBy default, these colors are inherited by all color-related core plugins, like `borderColor`, `divideColor`, `placeholderColor` and others.\n\nPlease note the following guidelines:\n\n1. This is a flat object (`{ 'gray-50': '#f9fafb' }`) not a nested on like in tailwind (`{ 'gray': { 50: '#f9fafb' } }`) uses.\n2. Colors should be in [#-hexadecimal notation](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value) (like `#RRGGBB` or `#RGB`) to work best with opacity plugins like `text-opacitiy` or `bg-opacitiy`.\n\n#### \"_On_\" colors\n\n\u003e provide accessible contrast to their base color - `on-primary` or `on-surface`\n\nWhenever elements, such as text or icons, appear in front of surfaces, those elements should use colors designed to be clear and legible against the colors behind them. When a color appears \"_on_\" top of a primary color, it’s called an \"_on primary color_\". They are labelled using the original color category (such as primary color) with the prefix `on-`.\n\n\"_On_\" colors are primarily applied to text, iconography, and strokes. Sometimes, they are applied to surfaces.\n\n\u003e The `bg-\u003ccolor\u003e` directive adds a default `color` CSS declaration if a corresponding `on-*` color is found. The reverse works as well: `bg-on-\u003ccolor\u003e` adds `bg-\u003ccolor\u003e` as `color`. The `color` set in a way it can be overridden using `text-\u003ccolor\u003e` (see [Selector Ordering](#selector-ordering)).\n\n## Dark Mode\n\nNow that dark mode is a first-class feature of many operating systems, it's becoming more and more common to design a dark version of your website to go along with the default design.\n\nTo make this as easy as possible, beamwind includes a dark variant that lets you style your site differently when dark mode is enabled:\n\n```js\nbw`\n  bg-white text-black\n  dark:(bg-gray-800 text-white)`\n```\n\n\u003e It's important to note that the dark mode variant is **always** enabled and available for all directives.\n\nNow whenever dark mode is enabled on the user's operating system, `dark:{directive}` classes will take precedence over unprefixed classes. The `media` strategy uses the [prefers-color-scheme media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) under the hood, but if you'd like to support toggling dark mode manually, you can also use the `class` strategy for more control:\n\n```js\nsetup({\n  darkMode: 'class', // default is 'media'\n  darkModeClass: 'dark-mode', // optional, default is 'dark'\n})\n```\n\nFor an example how to toggle dark mode manually read the [Tailwind Guide](https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually).\n\n## Plugins\n\nConceptual there are two kind of plugins:\n\n1. Utilities: these may return a CSS rule object to be injected into the page (eq: `{ 'text-color': 'red' }`)\n2. Components: these return directives which are resolved by utilities to their final class name (eq: `'bg-white text-red'`)\n\nNew plugins can be provided using the `setup` method. `setup` can be called multiple times where each call extends the existing configuration.\n\nPlugins are searched for by name using the longest prefix before a dash (`\"-\"'`). The name and the remaining parts (splitted by a dash) are provided as first argument to the plugin function. For example if the directive is `bg-gradient-to-t` the following order applies:\n\n| Plugin             | Parts                           |\n| ------------------ | ------------------------------- |\n| `bg-gradient-to-t` | `[\"bg-gradient-to-t\"]`          |\n| `bg-gradient-to`   | `[\"bg-gradient-to\", \"t\"]`       |\n| `bg-gradient`      | `[\"bg-gradient\", \"to\", \"t\"]`    |\n| `bg`               | `[\"bg\", \"gradient\", \"to\", \"t\"]` |\n\n### Adding New Utilities\n\nAlthough beamwind provides a [pretty comprehensive set of utility classes](https://github.com/kenoxa/beamwind/blob/main/packages/core/src/plugins.ts) out of the box, you may run into situations where you need to add a few of your own.\n\nStatic utilities can be defined as CSS declaration objects:\n\n```js\nsetup({\n  plugins: {\n    'text-important': { color: 'red' },\n  },\n})\n```\n\nSometimes a pseudo class or child selector maybe required. In these case use an array where the first value is appended to the generated class name in the selector and the second value is CSS declaration object. The next example shows how this can be use to implement a [Stretched link](https://v5.getbootstrap.com/docs/5.0/helpers/stretched-link/):\n\n```js\nsetup({\n  plugins: {\n    'stretched-link': [\n      '::after',\n      {\n        position: 'absolute',\n        top: '0',\n        right: '0',\n        bottom: '0',\n        left: '0',\n        'z-index': '1',\n        content: '\"\"',\n      },\n    ],\n  },\n})\n```\n\nMost utilities have some logic based on the directive value or need access to the current theme. For these case you can define a function which needs to return a CSS rule object, a decorator / rule tuple or a falsey value if it couldn't handle the provided directive parts.\n\n\u003e Dynamic plugins should be side-effect free and produce the same output given the same parameters.\n\nLets define a basic [scroll-snap](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type) utility. It should support these directives:\n\n- `scroll-snap-none`\n- `scroll-snap-x`\n- `scroll-snap-y`\n\n```js\nsetup({\n  plugins: {\n    // The directive splitted by '-' with the plugin name as first value: ['scroll-snap', ...]\n    'scroll-snap': (parts) =\u003e {\n      return { 'scroll-snap-type': parts[1] }\n    },\n  },\n})\n```\n\n\u003e As we are passing the second part through this additionally supports other values like `block`, `inline`, `both`, ...\n\u003e **Note**: This may lead to invalid css.\n\nWhat this currently does not support is something like `scroll-snap-both-mandatory`. Lets fix that:\n\n```js\n// ... same as before\nreturn { 'scroll-snap-type': parts.slice(1).join(' ') }\n```\n\nAs this is quite common beamwind provides two helper ([join](https://beamwind.js.org/packages/core/modules.html#join) and [tail](https://beamwind.js.org/packages/core/modules.html#tail)) for this:\n\n```js\nimport { join, tail } from 'beamwind'\n\n// ... same as before\nreturn { 'scroll-snap-type': join(tail(parts), ' ') }\n```\n\nAs a second parameter the plugin function receives a [theme value accessor](https://beamwind.js.org/packages/types/interfaces/themevalueresolver.html). We can use that to access configured theme values. This allows to provide aliases for directive parts. Lets allow these directives:\n\n- `scroll-snap` - using a default value\n- `scroll-snap-proximity` - using a theme value\n\n```js\nsetup({\n  // Add a new theme section; Not needed if you are re-using existing theme sections\n  theme: {\n    scroll: {\n      // eg: 'scroll-snap' =\u003e { scroll-snap-type: both; }\n      DEFAULT: 'both',\n      // eg: 'scroll-snap-proximity' =\u003e { scroll-snap-type: both proximity; }\n      proximity: 'both proximity',\n    }\n  }\n\n  plugins: {\n    'scroll-snap': (parts, theme) =\u003e {\n      // Omit the first element which is 'scroll-snap'\n      return { 'scroll-snap-type': theme('scroll', tail(parts)) }\n    }\n  }\n})\n```\n\nThis will fail for unknown theme values. To support the previous directives like `scroll-snap-x` we need to mark the value resolution as optional and provide a fallback value:\n\n```js\nreturn {\n  'scroll-snap-type': theme('scroll', tail(parts), true /* Optional */) || join(tail(parts), ' '),\n}\n```\n\n\u003e Responsive and state variants (like `hover`, `focus`, ...) are automatically applied. Opposed to tailwind there is no need to define which one should be applied.\n\n_Optional_ Typescript does not recognize this new section. Using [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) we can announce the new property:\n\n```ts\ndeclare module '@beamwind/types' {\n  interface Theme {\n    scroll: ThemeSection\n  }\n}\n```\n\n### Adding New Components\n\n\u003e Components define a set of utility directives that should be applied if the component directive is used.\n\nStatic components that are only a collection of utilities can be defined as strings. The following example allows to use `card` as a directive (`bw('card')`) which will be expanded to `max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl`:\n\n```js\nsetup({\n  plugins: {\n    card: 'max-w-md mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl',\n  },\n})\n```\n\nDynamic components can be implemented as function which should return a string of directives to be applied.\n\n```js\nsetup({\n  plugins: {\n    btn(parts) {\n      if (parts[1]) {\n        return `bg-${parts[1]} hover:bg-${parts[1]}-hover active:bg-${parts[1]}-active`\n      }\n\n      return 'font-bold py-2 px-4 rounded'\n    },\n  },\n})\n```\n\nSome dynamic components depend on additional logic and like to use the familiar `bw` API. For these cases beamwind provides the [apply](https://beamwind.js.org/packages/core/modules.html#apply) helper, which has the same [API signature as `bw`](#function-signature).\n\n```js\nimport { setup, apply } from 'beamwind'\n\nsetup({\n  plugins: {\n    btn(parts, theme) {\n      if (parts[1]) {\n        return apply`bg-${parts[1]} ${{ rounded: parts[1] === 'rounded }}`\n      }\n\n      return 'font-bold py-2 px-4 rounded'\n    },\n  },\n})\n```\n\n\u003e This is inspired by [@apply directive](https://tailwindcss.com/docs/functions-and-directives#apply) from Tailwind.\n\n### Inline Plugins\n\nA global plugin registry (per [beamwind instance](#instance-creation)) has it's downsides as each key/name must be unique. beamwind allows to define inline plugins ([API doc](https://beamwind.js.org/packages/types/modules.html#inlineplugin)) which are just like [normal plugins](#plugins) without the first parameter.\n\n\u003e Please take a look at [Plugin API documentation](#plugins) for further details about what a plugin can do.\n\n```js\nconst card = (theme) =\u003e ({\n  display: block\n  border: `1px solid ${theme('colors', 'primary')}`,\n  'text-align': 'center',\n})\n\nbw`font-bold ${card} text-primary`\n// =\u003e font-bold __card_1 text-primary\n\nbw('font-bold', card, 'text-primary')\n// =\u003e font-bold __card_1 text-primary\n\n// You can use variants\nbw`sm:${card} text-primary`\n// =\u003e font-bold sm:__card_1 text-primary\n\nbw({ sm: card }, 'text-primary')\n// =\u003e font-bold sm:__card_1 text-primary\n```\n\n\u003e **Note**: This should be a last resort as it comes with a small performance penalty.\n\n### Plugin Helper Functions\n\nbeamwind provides a small set of helper functions to write your own plugins:\n\n- [apply](https://beamwind.js.org/packages/core/modules.html#apply)\n- [corners](https://beamwind.js.org/packages/core/modules.html#corners)\n- [edges](https://beamwind.js.org/packages/core/modules.html#edges)\n- [expandEdges](https://beamwind.js.org/packages/core/modules.html#expandedges)\n- [join](https://beamwind.js.org/packages/core/modules.html#join)\n- [tail](https://beamwind.js.org/packages/core/modules.html#tail)\n\n## [Configuration](https://beamwind.js.org/packages/types/interfaces/configurationoptions.html)\n\n### Global Styles\n\nSometimes global CSS styles are required. beamwind support injection of CSS during the initialization using [`init`](https://beamwind.js.org/packages/types/interfaces/configurationoptions.html#init):\n\n```js\nsetup({\n  init(insert, theme) {\n    insert(`body{margin:${theme.spacing.xl}}`)\n  },\n})\n```\n\n### Catching Errors\n\nBy default warnings about missing translations will be written to the console.\n\nIt is possible to make beamwind throw an error rather just [warn](https://beamwind.js.org/packages/core/modules.html#warn) by opting into _[strict](https://beamwind.js.org/packages/core/modules.html#strict)_ [`mode`](https://beamwind.js.org/packages/types/interfaces/configurationoptions.html#mode):\n\n```js\nimport { strict } from 'beamwind'\n\nsetup({ mode: strict })\n```\n\nTo fully customize the error handling you can provide a `warn` function:\n\n```js\nimport { mode } from 'beamwind'\n\nsetup({\n  mode: mode((message) =\u003e {\n    /* ... */\n  }),\n})\n```\n\n\u003e The exports `warn`, `strict` and `mode` exports are re-exported by all packages.\n\nFor advanced use case you can implement your own [mode](https://beamwind.js.org/packages/types/interfaces/mode.html):\n\n```js\nimport { mode } from 'beamwind'\n\nsetup({\n  mode: {\n    unknown(section, keypath, optional, theme) {\n      /* ... */\n    },\n    warn(message, directive) {\n      /* ... */\n    },\n  },\n})\n```\n\n\u003e For an example see [@beamwind/preset-play](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play).\n\n### Autoprefix\n\nA custom auto-prefixer method may be used as a replacement for the built-in [tiny-css-prefixer](https://github.com/kitten/tiny-css-prefixer):\n\n```js\nimport { prefix as stylisPrefix } from 'stylis' // v4\n\nsetup({\n  // A custom solution which weighs more than the default\n  prefix: (property, value) =\u003e stylisPrefix(`${property}:${value};`, property.length).slice(0, -1),\n})\n```\n\n### Hashed Class Names\n\nbeamwind uses hashed class names (like `_1m4vcp0`) by default. During development or testing it maybe useful to use readable class names:\n\n```js\nsetup({ hash: false })\n```\n\nAlternatively a custom hash function can be provided:\n\n```js\nimport hash from '@emotion/hash'\n\nsetup({ hash: (string) =\u003e '_' + hash(string) })\n```\n\n### Injector\n\nAn injector is responsible for adding a CSS rule to its underlying target.\n\nDuring testing or server-side rendering the `virtualInjector` should be used:\n\n```js\nimport { virtualInjector } from 'beamwind'\n\nconst injector = virtualInjector()\nsetup({ injector })\n\ninjector.target // Array with sorted CSS rulesText\n```\n\n### Instance creation\n\nThere are some case where you need to create separate [instance](https://beamwind.js.org/packages/types/interfaces/instance.html) of beamwind:\n\n- for reduced bundle size by using a own preset\n- IE 11 support using [reset](https://github.com/kenoxa/beamwind/blob/main/packages/reset)\n\nBasically you need to do the following:\n\n```js\n// Choose either reset or preflight\nimport preflight from '@beamwind/preflight'\nimport { createInstance } from '@beamwind/core'\n\nimport yourTheme from './your-theme'\n\nexport const { bw, setup, theme } = createInstance([preflight(), yourTheme])\n```\n\n\u003e You can use one of the existing [packages](#packages) as a template.\n\n#### Multiple Browsing Contexts\n\nCreating a own beamwind instance is required if you want to manage styles of multiple browsing contexts (e.g. an `\u003ciframe\u003e` besides the main document).\n\n```js\nimport { createInstance, cssomInjector } from 'beamwind'\n\nconst iframeDocument = document.getElementsByTagName('iframe')[0].contentDocument\n\nexport const { bw } = createInstance({\n  injector: cssomInjector({\n    // Make sure this node exists or create it on the fly if necessary\n    target: iframeDocument.getElementById('__beamwind'),\n  }),\n})\n```\n\n\u003e This option should be used along with a custom target for injection.\n\n### Server-side rendering (SSR)\n\nBeamwind supports SSR. Consider the following example:\n\n```js\nimport { h } from 'preact'\nimport render from 'preact-render-to-string'\nimport htm from 'htm'\nimport { createInstance, virtualInjector } from 'beamwind'\n\nconst injector = virtualInjector()\nconst { bw } = createInstance({ injector })\n\nconst html = htm.bind(h)\nconst style = {\n  main: bw`clearfix`,\n}\n\nconst app = html`\u003cmain className=${style.main}\u003ehello beamwind\u003c/main\u003e`\nconst appHtml = render(app)\nconst styleTag = `\u003cstyle id=\"__beamwind\"\u003e${injector.target.join('\\n')}\u003c/style\u003e`\n\n// Inject styleTag to your HTML now.\n```\n\n\u003e We are planning to implement the style tag rendering via `getStyleTag(injector)` in a `@beamwind/ssr` package.\n\u003e The idea is that `@beamwind/ssr` would optimize the styles instead of simply joining them.\n\n\n### nonce\n\nIn order to prevent harmful code injection on the web, a [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/CSP) may be put in place. During server-side rendering, a cryptographic nonce (number used once) may be embedded when generating a page on demand:\n\n```js\nimport { virtualInjector } from 'beamwind'\n\n// Usage with webpack: https://webpack.js.org/guides/csp/\nconst injector = virtualInjector({ nonce: __webpack_nonce__ })\n```\n\nThe same nonce parameter should be supplied to the client-side:\n\n```js\nimport { setup } from 'beamwind'\n\nsetup({ nonce: __webpack_nonce__ })\n```\n\n### target\n\nChanges the destination of the injected rules. By default, a `\u003cstyle id=\"__beamwind\"\u003e element in the `\u003chead\u003e` during runtime, which gets created if unavailable.\n\n## Selector Ordering\n\n\u003e This section describes the internal ordering of the generated CSS rules. _beamwind takes care of this_\n\nbeamwind creates, except for a few exceptions, one CSS rule with a single class as selector per directive. This means thy have all the same specificity.\n\n\u003e If two declarations have the same weight, origin, and specificity, the latter specified wins.\n\nSome directives depend on each other. For example the [`via-\u003ccolor\u003e`](https://tailwindcss.com/docs/gradient-color-stops#middle-color) must be declared after the [`from-\u003ccolor\u003e`](https://tailwindcss.com/docs/gradient-color-stops#from-color) directive. As a result beamwind has to ensure that all CSS rules are in a specific order.\n\nThe following rules apply in deterministically sort the injected CSS rules:\n\n- media queries are sorted in a mobile first manner using the `min-width` value\n- other at-rules - based on `-:;,#(` counting\n- pseudo classes and variants are sorted in the following order: `first`, `last`, `odd`, `even`, `link`, `visited`, `empty`, `checked`, `group-hover`, `group-focus`, `focus-within`, `hover`, `focus`, `focus-visible`, `active`, `disabled`, others - meaning that `active` overrides `focus` and `hover` for example (see [When do the :hover, :focus, and :active pseudo-classes apply?](https://bitsofco.de/when-do-the-hover-focus-and-active-pseudo-classes-apply/#orderofstyleshoverthenfocusthenactive)\n- number of declarations (descending) - this allows single declaration styles to overwrite styles from multi declaration styles\n- greatest precedence of properties (ignoring vendor prefixed and custom properties) based on `-` counting - shorthand properties are inserted first eg longhand properties override shorthands.\n- greatest precedence of values based on counting `-:;,#(`\n\n## Roadmap\n\nTODO see TODO.md\n\n## Tailwind Differences\n\n\u003e Beamwind aims to support with Tailwind v2 and v1 (see [IE 11 Compatibilty](#ie-11-compatibility)). [Some features](#missing-features) are not yet implemented.\n\n- beamwind supports [variant](#variant-grouping) and [directive](#directive-grouping) grouping to reduce the overwhelming maze Tailwind sometimes creates\n- beamwind theme has a slightly different format:\n  - `colors` is a [flat-object](#colors)\n  - `fontFamily`s are strings\n  - `animation` additionally accepts a [tuple form](https://beamwind.js.org/packages/types/modules.html#themeanimation) to infer the key within [keyframes](https://beamwind.js.org/packages/types/interfaces/theme.html#keyframes) which waypoints should be injected\n  - values maybe [theme resolvers](#referencing-other-values)\n- beamwind supports [_\"on\"_ colors](#on-colors)\n- beamwind automatically infers negated values - they do _not_ need to be in the theme config\n\n### Missing Features\n\nThe following Tailwind v2 features are not yet available in beamwind:\n\n- [Container](https://tailwindcss.com/docs/container)\n- [Font Variant Numeric](https://tailwindcss.com/docs/font-variant-numeric)\n\n\u003e Did we miss a feature? Please [open a an issue](https://github.com/kenoxa/beamwind/issues/new) or [contribute](#contribute) a pull request.\n\n### Additional Features\n\n- `d-*`: allows to set the `display` property (from [bootstrap](https://v5.getbootstrap.com/docs/5.0/utilities/display/))\n- `appearance-*`: supports [all values](https://developer.mozilla.org/en-US/docs/Web/CSS/appearance)\n- `bg-\u003ccolor\u003e`: if a \"_on_\" color) (`on-\u003ccolor\u003e`) is found it is used as default CSS `color`; to change to a different color use `text-\u003ccolor\u003e` (tailwind style)\n- `bg-gradient-to-*` is built-in, no need to configure these\n- `text-underline`, `text-no-underline`, `text-line-through`, `text-uppercase`, `text-lowercase` and `text-capitalize`: this allows grouping of text directives like `text(lg red-500 capitalize underline)`\n- `font-italic` and `font-no-italic`: this allows grouping of font directives like `font(sans italic bold)`\n- `border` and `divide` allow to combine positions (`t`op, `r`righ, `l`eft, `b`ottom)\n\n  - `tr` - `top` \u0026 `right`\n  - `brl` - `bottom`, `right` and `left`\n\n  \u003e **Note** `x` and `y` can not be combined.\n\n- `rotate`, `scale` , `skew` and `translate` provide a fallback for IE 11\n\n  \u003e `transform rotate-45` works but when using `transform rotate-45 scale-150` only one of both is applied.\n\n### IE 11 compatibility\n\n\u003e Some new tailwind features use [CSS Variables (Custom Properties)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) and are therefore not compatible with [IE 11](https://caniuse.com/css-variables).\n\nBeamwind includes fallbacks for the following directives which mimic [Tailwind v1](https://v1.tailwindcss.com/) behavior:\n\n- Color Opacity\n  - [border-opacity-\\*](https://tailwindcss.com/docs/border-opacity)\n  - [bg-opacity-\\*](https://tailwindcss.com/docs/background-opacity)\n  - [text-opacity-\\*](https://tailwindcss.com/docs/text-opacity)\n  - [placeholder-opacity-\\*](https://tailwindcss.com/docs/placeholder-opacity)\n- Reversing Children Order\n  - [divide-\\*-reverse](https://tailwindcss.com/docs/divide-width#reversing-children-order)\n  - [space-\\*-reverse](https://tailwindcss.com/docs/space#reversing-children-order)\n- `rotate`, `scale` , `skew` and `translate` can only be used alone\n\n  \u003e `rotate-45` works but when using `rotate-45 scale-150` only one of both is applied. In that case you must use `transform`: `transform rotate-45 scale-150`\n\nSome directive only work with CSS Variables and are not supported in IE 11:\n\n- [Ring](https://tailwindcss.com/docs/ring-width)\n\n## Oceanwind Differences\n\n\u003e All [Tailwind Differences](#tailwind-differences) apply as well.\n\nThis library is heavily inspired and based on [oceanwind]. Without the work of [Luke Jackson](https://github.com/lukejacksonn) this would not have been possible! He wrote a great [blog post](http://blog.lukejacksonn.com/oceanwind) about the development of oceanwind.\n\nSome notable differences are:\n\n- oceanwind supports duplicate directives tracking\n- beamwind is 7-10 times faster than oceanwind (see [Benchmarks](https://github.com/kenoxa/beamwind/blob/main/benchmarks))\n- beamwind API [additionally supports](#function-signature)\n\n  - variadic arguments like `bw('bg-blue', 'text-white')`\n  - [Directive Grouping](#directive-grouping)\n  - Tagged Template Interpolation values may additionally be Array, Object or Function ([inline plugins](#inline-plugins))\n  - Object values which are String, Array or Object start a new variant group\n  - support for [inline plugins](#inline-plugins)\n\n- beamwind allows to define new plugins (see [Plugins](#plugins))\n- beamwind allows to generate [readable class names](#hashed-class-names)\n- beamwind adheres to the pseudo class and variant order as used by tailwind\n- beamwind uses [`calc()`](\u003chttps://developer.mozilla.org/en-US/docs/Web/CSS/calc()\u003e) to negate values - this allows to use complex expression as theme values\n- beamwind supports additional tailwind features like\n\n  - [Dark Mode](https://tailwindcss.com/docs/dark-mode)\n  - [animation](https://tailwindcss.com/docs/animation)\n  - [font-size with default line-height](https://tailwindcss.com/docs/font-size#providing-a-default-line-height)\n  - [font-size with default letter-spacing](https://tailwindcss.com/docs/font-size#providing-a-default-letter-spacing)\n  - [overflow-ellipsis](https://tailwindcss.com/docs/text-overflow#overflow-ellipsis)\n  - [overflow-clip](https://tailwindcss.com/docs/text-overflow#overflow-clip)\n  - [transition](https://tailwindcss.com/docs/transition-property) with default timing function and duration\n  - [animate](https://tailwindcss.com/docs/animate)\n  - [transform](https://tailwindcss.com/docs/transform) and [transform-gpu](https://tailwindcss.com/docs/transform#hardware-acceleration)\n  - [Background Image](https://tailwindcss.com/docs/background-image)\n  - [Gradient Color Stops](https://tailwindcss.com/docs/gradient-color-stops)\n  - [ring](https://tailwindcss.com/docs/ring-width)\n  - [auto-cols-\\*](https://tailwindcss.com/docs/grid-auto-columns) and [auto-rows-\\*](https://tailwindcss.com/docs/grid-auto-rows)\n  - [divide-\\*-reverse](https://tailwindcss.com/docs/divide-width#reversing-children-order) and [space-\\*-reverse](https://tailwindcss.com/docs/space#reversing-children-order)\n  - [Background Clip](https://tailwindcss.com/docs/background-clip)\n  - [place-content-\\*](https://tailwindcss.com/docs/place-self), [place-items-\\*](https://tailndcss.com/docs/place-items) and [place-self-\\*](https://tailwindcss.com/docs/place-self)\n  - [Overscroll Behavior](https://tailwindcss.com/docs/overscroll-behavior)\n  - [Hover, Focus, \u0026 Other States](https://tailwindcss.com/docs/hover-focus-and-other-states)\n    - [group-hover](https://tailwindcss.com/docs/hover-focus-and-other-states#group-hover)\n    - [group-focus](https://tailwindcss.com/docs/hover-focus-and-other-states#group-focus)\n    - [motion-safe](https://tailwindcss.com/docs/hover-focus-and-other-states#motion-safe)\n    - [motion-reduce](https://tailwindcss.com/docs/hover-focus-and-other-states#motion-reduce)\n    - [first-child](https://tailwindcss.com/docs/hover-focus-and-other-states#first-child)\n    - [last-child](https://tailwindcss.com/docs/hover-focus-and-other-states#last-child)\n    - [odd-child](https://tailwindcss.com/docs/hover-focus-and-other-states#odd-child)\n    - [even-child](https://tailwindcss.com/docs/hover-focus-and-other-states#even-child)\n\n- beamwind does not generate strictly atomic CSS\n\n  Some tailwind classes like [font-size](https://tailwindcss.com/docs/font-size) are comprised of several CSS declarations.\n  They must be in one CSS declaration block to be overridden by single CSS declarations liken [line-heigth](https://tailwindcss.com/docs/line-height).\n\n### Size Comparison\n\n| \u0026nbsp;   | [oceanwind](\u003c(https://bundlephobia.com/result?p=oceanwind)\u003e)                                                                     | [beamwind](\u003c(https://bundlephobia.com/result?p=@beamwind/core)\u003e)                                                                          |\n| -------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |\n| minified | [![Oceanwind Minified](https://flat.badgen.net/bundlephobia/min/oceanwind?label)](https://bundlephobia.com/result?p=oceanwind)   | [![Beamwind Minified](https://flat.badgen.net/bundlephobia/min/@beamwind/core?label)](https://bundlephobia.com/result?p=@beamwind/core)   |\n| gzipped  | [![Oceanwind Gzipped](https://flat.badgen.net/bundlephobia/minzip/oceanwind?label)](https://bundlephobia.com/result?p=oceanwind) | [![Beamwind Gzipped](https://flat.badgen.net/bundlephobia/minzip/@beamwind/core?label)](https://bundlephobia.com/result?p=@beamwind/core) |\n\n## Browser Support\n\nAll versions of Node.js are supported.\n\nAll browsers that support [Array.isArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#Browser_compatibility) and [Object.keys](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Browser_compatibility) are supported (IE9+).\n\n[Some directives](#ie-11-compatibility) use fallbacks for IE 11.\n\n## Acknowledgements\n\nWithout these libraries and their authors this would not have been possible:\n\n- [Tailwind CSS]\n- [Oceanwind]\n- [Otion]\n- [cslx](https://www.npmjs.com/package/cslx)\n- [Braid Design System](https://seek-oss.github.io/braid-design-system)\n\n## Contribute\n\nThanks for being willing to contribute!\n\n\u003e This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/beamwind/beamwind/issues) if you have any idea, question, or you've found a bug.\n\n**Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)\n\nWe are following the [Conventional Commits](https://www.conventionalcommits.org) convention.\n\n### Develop\n\nClone the repository and cd into the project directory.\n\nRun `yarn install \u0026\u0026 yarn build`.\n\nCd into the package that you'd like to make progress on.\n\n- `yarn test`: Run test suite including linting\n- `yarn format`: Ensure consistent code style\n- `yarn build`: Build all packages\n- `yarn publish`: To publish all changed packages\n\n### Sponsors\n\n[![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com)\n\n## License\n\n[MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com)\n\n[tailwind css]: https://tailwindcss.com\n[oceanwind]: https://www.npmjs.com/package/oceanwind\n[otion]: https://www.npmjs.com/package/otion\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenoxa%2Fbeamwind","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkenoxa%2Fbeamwind","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkenoxa%2Fbeamwind/lists"}