use `lightningcss` and `prettier` for `toMatchFormattedCss`
Lightning CSS applies some optimizations and prettier ensures that the
output is always formatted in the same way.
In a future version, we will be using Lightning CSS to apply
optimizations like handling the nesting, optimizing selectors, sorting
declarations, simplifying colors and so on.
To guarantee that we have the same output in both the normal version and
OXIDE version, we can apply lightningcss in our tests so that it always
produces correct results in both version with the same optimizations
applied.
This also aliases `toMatchCss` to `toMatchFormattedCss` so that we can
guarantee the same output. This has a small caveat where `lightningcss`
is pretty strict. It will complain about `@media screen(md) {}` for
example. This is correct because it is not valid CSS, but we eventually
take care of it.
In this case, we will catch the error and use prettier instead (since
this should only happen in tests that doesn't use end-to-end tests, but
uses a more specialized test instead). If prettier still finds an error,
we will ensure to throw the original error.
Eventually, all the "lower" level tests, should probably become higher
level end-to-end tests. But let's do everything step by step!
- Setup the codebase to be able to use the Rust parts based on an
environment variable: `OXIDE=1`.
- Setup some tests that run both the non-Rust and Rust version in the
same test.
- Sort the candidates in a consistent way, to guarantee the order for
now (especially in tests).
- Reflect sorting related changes in tests.
- Ensure tests run in both the Rust and non-Rust version. (Some tests
are explicitly skipped when using the Rust version since we haven't
implemented those features yet. These include: custom prefix,
transformers and extractors).
- `jest`
-`OXIDE=1 jest`
* 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>
* 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 `any` data type for decoration color plugin
The main reason for the `any` type is so that we don't have to parse the
value and can assume that this plugin handles "any" value you give it.
This is useful because `decoration-[var(--something)]` would be
correctly translated to the correct decoration property. However, we
introduce another plugin with the same `decoration` prefix.
This means that now both `textDecorationColor` and
`textDecorationThickness` have the same base utility name: `decoration`.
- `textDecorationColor` had ['color', 'any']
- `textDecorationThickness` had ['length', 'percentage']
This means that `3px` fit both in the `length` data type of the
`textDecorationThickness` plugin and in the `any` data type of the
`textDecorationColor` plugin.
Removing the `any` fixes this.
TL;DR: Only have `any` when there are no conflicting utility names.
* remove utility that doesn't generate css
Having `decoration-[var(--abc)]` is ambiguous because there are multiple
plugins that have a `decoration` utility name. In order for this to work
you have to prefix it with the type: `decoration-[color:var(--abc)]`
which is already tested in this file.
* Add new outline style, color, width and offset utilities
Co-Authored-By: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
* Remove old `outline` property from default config
Co-Authored-By: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
* Tweak order of outline plugins
Co-Authored-By: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
* Revert to previous `outline-none` styles
Co-Authored-By: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
* Drop quotes from outline property
* Add offset back to `outline-none` utility
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
* remove unused `withRule`
* ensure all ::before and ::after elements have content
* update --tw-content for the content plugin
* simplify `before` and `after` variants
* update tests, to reflect changes
* make new `format` and `wrap` API's private for now
* allow returning a format string from `addVariant` callback
* add `content: var(--tw-content)` for before/after variants
* update tests to add `content: var(--tw-content)`
* update changelog
* utilities and tests in place for textDecorationColor and textDecorationOpacity
* change 'backgroundColor' to 'textDecorationColor' in corePlugin declaration for latter
* remove explicit textDecorationOpacity utility (the JIT slash syntax suffices)
Co-authored-by: Michael Warner <michaelwarner@Michaels-MacBook-Pro.local>
This adds `grow-*` and `shrink-*` utilities as aliases for `flex-grow-*` and `flex-shrink-*` since those names are unnecessarily verbose. We will stop documenting the long form ones and consider them deprecated.
```diff
- <div class="flex-grow-0 flex-shrink">
+ <div class="grow-0 shrink">
```
* simplify `inset` plugin
* run `prettier` on stub file
* simplify `align` utility
* improve arbitrary support for outline
This will allow us to use `outline-[OUTLINE,OPTIONAL_OFFSET]`
Input:
```html
outline-[2px_solid_black]
```
Output:
```css
.outline-\[2px_solid_black\] {
outline: 2px solid black;
outline-offset: 0;
}
```
---
Input:
```html
outline-[2px_solid_black,2px]
```
Output:
```css
.outline-\[2px_solid_black\2c 2px\] {
outline: 2px solid black;
outline-offset: 2px;
}
```
* remove default `type`
* simplify createUtilityPlugin, use types directly
* find first matching type when coercing the value
* introduce css data types
Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Types
These data types will be used to "guess" the type of an arbitrary value
if there is some ambiguity going on. For example:
```
bg-[#0088cc] -> This is a `color` -> `background-color`
bg-[url('...')] -> This is a `url` -> `background-image`
```
If you are using css variables, then there is no way of knowing which
type it is referring to, in that case you can be explicit:
```
bg-[color:var(--value)] -> This is a `color` -> `background-color`
bg-[url:var(--value)] -> This is a `url` -> `background-image`
```
When you explicitly pass a data type, then we bypass the type system and
assume you are right. This is nice in a way because now we don't have to
run all of the guessing type code. On the other hand, you can introduce
runtime issues that we are not able to detect:
```
:root {
--value: 12px;
}
/* Later... */
bg-[color:var(--value)] -> Assumes `color` -> *eventually* -> `background-color: 12px`
```
* add a bunch of new tests for advanced arbitrary values
* add url to resolveArbitraryValue list
* add `asURL` data type
* add `bg-[url('..')]` regex
* allow for `resolveArbitraryValue` to be an array
* prevent spaces around `-` when in a `url`
* add tests to verify `bg-[url('...')]` and `stroke-[url(...)]`
* move to real regexes
These regexes are only calculated once so we don't really have a
performance penalty here. However, it's a bit nicer to do it this way
because now you don't have to think about the proper escapes.
/.*/.source will basically take the source of the regex ".*" without
flags and converts it to a string with the proper escapes for you.
Fun fact, this `.source` property has been supported since Chrome,
Firefox and Safari version 1.
* allow for `'>'` in `content-['>']`
* Replace `culori` with simple color parser
* Use space-separated color syntax
* Update default color values to use space-separated syntax
* Update separator regex
* Fix tests
* add tests for the new `color` util
Also slightly modified the `color` util itself to take `transparent`
into account and also format every value as a string for consistency.
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
* move `./tests/jit` to `./tests`
* make tests consistent
Abstracted a `run` function and some syntax highlighting helpers for
`html`, `css` and `javascript`.
2021-09-03 13:48:16 +02:00
Renamed from tests/jit/arbitrary-values.test.css (Browse further)