* Improve type checking for formal syntax
* Add test
* Change order of test class name
* fix failing tests
* prefer `position` over `size` for backwards compatibility reasons
Previously `bg-[10px_10%]` generated `background-position: 10px 10%` before we introduced the fallback plugins.
Therefore we should prefer `position` over `size` as the default for backwards compatibility.
* update changelog
* ensure correct order
Thanks Prettier!
* update changelog
Co-authored-by: lzt1008 <lzt1008@live.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: liangzhengtai <liangzhengtai_i@didiglobal.com>
* use test with non-any type plugin
* choose backgroundSize over backgroundPosition
Ensure that `backgroundColor` can take any value
* add tests to verify fallback plugins
* implement fallback plugins
Whenever an arbitrary value results in css from multiple plugins we
first try to resolve a falback plugin.
The fallback mechanism works like this:
- If A has type `any` and B has type `color`, then B should win.
> This is because `A` will match *anything*, but the more precise type
should win instead. E.g.: `backgroundColor` has the type `any` so
`bg-[100px_200px]` would match both the `backgroundColor` and
`backgroundSize` but `backgroundSize` matched because of a specific
type and not because of the `any` type.
- If A has type `length` and B has type `[length, { disambiguate: true }]`, then B should win.
> This is because `B` marked the `length` as the plugin that should
win in case a clash happens.
* Add any type to a handful of plugins
Needs tests tho
* Add any type to `border-{x,y,t,r,b,l}` plugins
* Add test for any type
* Split on multiple lines
* fixup
* add tests for implicit `any` types
* rename `disambiguate` to `preferOnConflict`
* update tests to reflect `any` types a bit better
* update changelog
* annotate any-type test with a bit more information
Just for future debugging reasons!
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* support `sort` function in `matchVariant`
This will ensure that we can sort arbitrary variant values (and
hardcoded values) to ensure the order.
* update changelog
* Update lockfile
* Tweak formatting
* Refactor content path parsing
* Allow resolving content paths relative to the config file
* Include resolved symlinks as additional content paths
* Update changelog
* Work on suite of tests for content resolution
* reformat integration test list
* Move content resolution tests to integration
* Update future and experimental types
* ✨ Add `word-break: keep-all` with `keep-all`
ref. https://developer.mozilla.org/en-US/docs/Web/CSS/word-break
`whitespace-nowrap` and `word-break: keep-all` behave differently in different browsers.
Demo: https://jsfiddle.net/h1aj6nvy/
There is a difference between Firefox and Google chrome.
* Rename `keep-all` to `break-keep`
Co-authored-by: Jonathan Reinink <jonathan@reinink.ca>
* ignored `undefined` and `null` value values for intellisense
We are not completely ignoring "all" falsey values, because then we
would get rid of `0` values (e.g.: `p-0`) which is not what we want.
* update changelog
* convert the `matchVariant` to look more like `addVariant`
With the biggest difference that the `matchVariant` will have a callback
function that receives the current value of the variant.
* use object as argument for `matchVariant` callback
This will allow us to add more properties in the future if needed
without breaking changes.
- This is a breaking change: `(value) => ...` -> `({ value, other }) => ...`
- This is **not** a breaking change: `({ value }) => ...` -> `({ value, other }) => ...`
* add types for `matchVariant`
* improve split logic by delimiter
The original RegEx did mostly what we want, the idea is that we wanted
to split by a `,` but one that was not within `()`. This is useful when
you define multiple background colors for example:
```html
<div class="bg-[rgb(0,0,0),rgb(255,255,255)]"></div>
```
In this case splitting by the regex would result in the proper result:
```js
let result = [
'rgb(0,0,0)',
'rgb(255,255,255)'
]
```
Visually, you can think of it like:
```
┌─[./example.html]
│
∙ 1 │ <div class="bg-[rgb(0,0,0),rgb(255,255,255)]"></div>
· ──┬── ┬ ─────┬─────
· │ │ ╰─────── Guarded by parens
· │ ╰───────────────── We will split here
· ╰───────────────────── Guarded by parens
│
└─
```
We properly split by `,` not inside a `()`. However, this RegEx fails
the moment you have deeply nested RegEx values.
Visually, this is what's happening:
```
┌─[./example.html]
│
∙ 1 │ <div class="bg-[rgba(0,0,0,var(--alpha))]"></div>
· ┬ ┬ ┬
· ╰─┴─┴── We accidentally split here
│
└─
```
This is because on the right of the `,`, the first paren is an opening
paren `(` instead of a closing one `)`.
I'm not 100% sure how we can improve the RegEx to handle that case as
well, instead I wrote a small `splitBy` function that allows you to
split the string by a character (just like you could do before) but
ignores the ones inside the given exceptions. This keeps track of a
stack to know whether we are within parens or not.
Visually, the fix looks like this:
```
┌─[./example.html]
│
∙ 1 │ <div class="bg-[rgba(0,0,0,var(--alpha)),rgb(255,255,255,var(--alpha))]"></div>
· ┬ ┬ ┬ ┬ ┬ ┬ ┬
· │ │ │ │ ╰───┴───┴── Guarded by parens
· │ │ │ ╰────────────────── We will split here
· ╰─┴─┴──────────────────────────────── Guarded by parens
│
└─
```
* use already existing `splitAtTopLevelOnly` function
* add faster implemetation for `splitAtTopLevelOnly`
However, the faster version can't handle separators with multiple
characters right now. So instead of using buggy code or only using the
"slower" code, we've added a fast path where we use the faster code
wherever we can.
* use `splitAtTopLevelOnly` directly
* make split go brrrrrrr
* update changelog
* remove unncessary array.from call
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* Remove remnants of the user layer
It hasn’t been used in a while
* Rewrite sort offset generation
* wip
* wip
wip
* Handle parasite utilities
* wip
* wip
* Make parallel variants sorting more resillient
It’s not perfect but it’s close
* fix
* remove todo
it adds a new bit so it can’t
* Simplify getClassOrder usage
* Simplify
oops
oops
* Add parasite utility for `dark`
dark mode class name
* Cleanup
* Cleanup
* Simplify
* format files
* Fix prettier plugin to use git build of Tailwind CSS
Symlink and build instead of adding a recursive dev dependency
It breaks node < 16
* Fix prettier error
* wip
* fix test
* Update changelog
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
* Fix issue with Tailwind modifying global state
When running Tailwind, it modifies the plugin defaults parameters. As a
result Tailwind using a Tailwind plugin in the same process twice yields
different results.
* Add failing test
* Undo defaults change
* wip
* Fix shared mutation problem
* Update changelog
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* Don’t re-add files in the CLI watcher that are covered by dynamic patterns
They don’t have the same problem. As long as the parent directory is watched their add/change events will fire correctly
* Ignore raw events for files that don’t match the content files
* fixup
* Update changelog
It’s no longer necessary. If we have an entry in the `candidateRuleCache` then it’ll also be in the class cache and vice-versa. Also, we weren’t adding rules when hitting that cache like we should’ve been.
* Fix CLI not watching atomically renamed files
Chokdar should take care of this itself but sometimes it doesn’t do so OR is otherwise very sensitive to timing problems
* Force chokidar to always check for atomic writes
* Handle repeated atomic saves by retrying file reads
* Update changelog
* Honor the `hidden` attribute on elements
You’ll still be able to override this with utilities but this ensures that things like `<iframe hidden>` work as expected
* Update changelog