* Pick up changes from files that are both context and content deps
We switched to absolute paths and it broke this revealing a lurking bug. Fun.
* Update changelog
* Update changelog
* fix#9655
* update changelog
* add test for making sure calling variantFn doesn't crash
* make it behave as-if modifiers didn't exist
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
* remove redundant closing bracket in regex pattern
* test fractional spacing values in theme function
* add test that ensures arbitrary properties are separate
* update changelog
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
Before we were just checking if the `modifiers` option is `any` or an
object, without actually checking that in case it is an object, the
value actually existed.
* Record and watch PostCSS dependencies in the CLI
* ensure `changedContent` gets cleared
Otherwise this list gets bigger and bigger, not only that there is a
subtle bug. The moment you save a `.css` file we want to create a new
context and start from scratch. However, since the list was never
cleared, it meant that every subsequent save to *any* file (not only
config / css files) creates a new context...
By clearing the least we should work around this problem.
* add test that verifies an odd bug
The story goes like this:
1. add `underline` to html file
-> css contains `underline` rule
2. add `font-bold` to html file
-> css contains `underline` and `font-bold`
3. remove `underline` from html file
-> css still contains `underline` and `font-bold` for performance reasons
4. Save a css file (! RED FLAG)
-> css contains `font-bold` because we started from scratch
5. add `underline` to html file
-> css contains `underline` and `font-bold`
6. remove `underline` from html file
-> css only contains `font-bold`... (UH OH)
This is because the moment we did step 4, every single save in any file created a new context. Every. Single. Time.
* use a property that doesn't require `autoprefixer`
* update changelog
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
This means that if you define your `matchVariant` as:
```js
matchVariant('foo', (value) => '.foo-${value} &')
```
Then you can't use `foo:underline`, if you want to be able to use
`foo:underline` then you have to define a `DEFAULT` value:
```js
matchVariant('foo', (value) => '.foo-${value} &', {
values: {
DEFAULT: 'bar'
}
})
```
Now `foo:underline` will generate `.foo-bar &` as a selector!
* update changelog
* ensure `--content` is taken into account
* cleanup tests
- Use `rm` instead of deprecated `rmdir`
- Type the returnType correctly
* use a file not included in `content` of your tailwind.config.js file
* add `context.getVariants`
* use `modifier` instead of `label`
* handle `modifySelectors` version
* use reference
* reverse engineer manual format strings if container was touched
* use new positional API for `matchVariant`
* update changelog
* Add data variant
* Update CHANGELOG.md
Co-authored-by: Jonathan Reinink <jonathan@reinink.ca>
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
* Rename test variants
* Allow internally negating screens
* Refactor
* Add min/max screen variants
* wip
* Update changelog
* Update tests
* Sort list of variants properly
Technically each test isn’t 100% sorted right in isolation because prettier decisions are basically project-wide. This is close enough though.
* Update tests
* Change `matchVariant` API to use positional arguments
* Fix CS
wip
* Change match variant wrap modifier in an object
Needed for compat w/ some group and peer plugins
* Add modifier support to matchUtilities
* refactor
* Hoist utility modifier splitting
* Rename fn
* refactor
* Add support for generic utility modifiers
* Fix CS
* wip
* update types
* Warn when using modifiers without the option
* Allow modifiers to be a config object
* Make sure we can return null from matchUtilities to omit rules
* Feature flag generalized modifiers
We’re putting a flag for modifiers in front of matchVariant and matchUtilities
* cleanup
* Update changelog
* Properly flag variants using modifiers
* Fix test
* setup for container queries
* remove container query implementation itself
This will be moved to its own plugin.
* update changelog
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* add ability to add a `label`
This could be used for named groups or named container queries in the
future.
* expose `container` to `matchVariant`
Ideally we don't have to do this. But since we will be implementing
`group` and `peer` using the `matchVariant` API, we do require it for
the `visited` state.
* implement `group` and `peer` using the `matchVariant` API
* remove feature flag for `matchVariant`
* update changelog
* 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>