5412 Commits

Author SHA1 Message Date
Robin Malfait
558dcd568b
Fix v4 release workflow (#14167)
This PR fixes the release workflow

- We added a postbuild step so that any arguments/flags passed to the
`pnpm run build` command are forwarded to the underlying command.
- We made sure that we run any `pnpm` specific flags before the actual
command
- Cleaned up the CI workflow a bit
2024-08-09 19:57:16 +02:00
Robin Malfait
f5f91ce9de
Prepare v4.0.0-alpha.19 (#14162)
Prepare next `4.0.0-alpha.19` release
2024-08-09 17:58:30 +02:00
Jordan Pittman
759c1a37a9
Unify implementations of compile and __unstable__loadDesignSystem (#14150)
Right now there's some minor duplication and a ton of missing stuff in
`__unstable__loadDesignSystem` — this PR makes sure the functionality is
unified between it and `compile()`
2024-08-09 11:43:33 -04:00
Jordan Pittman
f06472eb95
Add matchUtilities and addUtilities APIs (#14114)
This PR introduces support for the v3-like `addUtilities` and
`matchUtilities` APIs in v4. We anticipate designing a new API that
feels more native to the way v4 works before shipping v4.0 stable, but
we're continuing to support these APIs for backwards compatibility.

We've tried to make the behavior as identical as possible, but because
of fundamental differences between the v3 and v4 engines there are a few
things that work differently:

## Only simple single-class selectors are supported

In v3 you could pass a complex CSS selector to `addUtilities` and we
would generate a utility for every class in the selector. In v4 we only
allow you to use a simple, single-class selector.

You should use nesting if you need a more complex selector, or need to
include at-rules like `@media` or `@supports`.

```js
// v3
function ({ addUtilities }) {
  addUtilities({
    '.scrollbar-none::-webkit-scrollbar': {
      display: 'none',
    },
  })
}

// v4
function ({ addUtilities }) {
  addUtilities({
    '.scrollbar-none': {
      '&::-webkit-scrollbar': {
        display: 'none',
      },
    },
  })
}
```

If you were adding custom utilities that included two classes and were
depending on both of those classes behaving like utilities (they could
each be used with variants), those custom utilities will need to be
rewritten as two separate utilities that each use nesting:

```js
// v3
function ({ addUtilities }) {
  addUtilities({
    '.section > .row': {
      color: 'red',
    },
  })
}

// v4
function ({ addUtilities }) {
  addUtilities({
    '.section': {
      '& > .row': {
        color: 'red',
      },
    },

    '.row': {
      'section > &': {
        color: 'red',
      },
    },
  })
}
```

We may introduce support for this in the future if this limitation turns
out to be a huge pain in the ass, but crossing our fingers that people
were mostly doing simple stuff here.

## Opacity modifiers support bare values

To be consistent with how built-in utilities work in v4, custom
utilities that specify `type: "color"` now get "bare value" support for
opacity modifiers. This means that a utility like `foo-black/33` will
work out of the box without having to either add `--opacity-33` to your
theme nor would you need to add it to the `modifiers` option.

## The `preferOnConflict` type option is gone

In v3 we introduced an internal API called `preferOnConflict` for types.
This was used as a way to disambiguate between two utilities with the
same "root" but which produced different properties which used the same
CSS data types. This was only applicable to arbitrary values and was
only used for disambiguating between `background-position` and
`background-size`.

In v4, both of these properties are handled by a single plugin meaning
this feature is no longer necessary. No one should've really been using
this option anyway as it was never documented so we're dropping the
feature.

## The options `respectPrefix` and `respectImportant` are not yet
supported

Neither the `prefix` nor `important` features exist in any form in v4 at
this time. Therefore, they are not currently supported by this PR. We
will look into supporting them if/when those features return.

## The `theme(…)` function is not currently supported

Custom utilities defined using `matchUtilities` often use the `theme(…)`
function to define their default values, but we haven't implemented
support for `theme(…)` yet in v4.

This means that as of this PR, default values for custom utilities must
be hardcoded:

```js
function ({ matchUtilities }) {
  matchUtilities({
    'tab': (value) => {
      return {
        'tab-size': value,
      }
    },
  }, {
    values: {
      2: '2',
      4: '4',
      8: '8',
    },
  })
}
```

Getting `theme(…)` working is a big project so we're going to tackle it
in a separate PR.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-09 11:34:27 -04:00
Robin Malfait
d223112162
Bump dependencies (#14160)
This PR bumps dependencies

We also make some dependencies `catalog:` dependencies, which allows us
to keep
the version in sync. E.g.: `lightningcss` and `@types/node`.

Bumped `turbo` to the latest version + enabled the new UI

Fixed a bug in the tests now that `lightningcss` outputs the correct
value.
2024-08-09 16:12:24 +02:00
Robin Malfait
7d73e51359
Ensure @apply works inside @utility (#14144)
This PR fixes an issue where `@apply` was not handled if it was used
inside of `@utility`.

You should now be able to do something like this:
```css
@utility btn {
  @apply flex flex-col bg-white p-4 rounded-lg shadow-md;
}
```

If you then use `btn` as a class, the following CSS will be generated:
```css
.btn {
  border-radius: var(--radius-lg, .5rem);
  background-color: var(--color-white, #fff);
  padding: var(--spacing-4, 1rem);
  --tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
  --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  flex-direction: column;
  display: flex;
}
```

This PR also makes sure that you can use custom `@utility` inside other
`@utility` via `@apply`. E.g.:
```css
@utility foo {
  color: red;
}

@utility bar {
  color: red;
  @apply hover:foo;
}
```

If we detect a circular dependency, then we will throw an error since
circular dependencies are not allowed. E.g.:
```css
@utility foo {
  @apply hover:bar;
}

@utility bar {
  @apply focus:baz;
}

@utility baz {
  @apply dark:foo;
}
```
Regardless of which utility you use, eventually it will apply itself.

Fixes: #14143
2024-08-09 16:09:25 +02:00
Philipp Spiess
b01ff53f2a
Vite: Support Tailwind in Vue <style> blocks (#14158)
This PR adds support to transforming `<style>` blocks emitted by Vue
components with tailwindcss when the `@tailwindcss/vite` is used.

Example:

```vue
<style>
  @import 'tailwindcss/utilities';
  @import 'tailwindcss/theme' theme(reference);
  .foo {
    @apply text-red-500;
  }
</style>
<template>
 <div class="underline foo">Hello Vue!</div>
</template>
```

Additionally, this PR also adds an integration test.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-09 12:41:58 +02:00
Jordan Pittman
1fdf67989f Remove errant console log calls 2024-08-08 15:29:47 -04:00
Philipp Spiess
921b4b673b
Use import to load plugins (#14132)
Alternative to #14110

This PR changes the way how we load plugins to be compatible with ES6
async `import`s. This allows us to load plugins even inside the browser
but it comes at a downside: We now have to change the `compile` API to
return a `Promise`...

So most of this PR is rewriting all of the call sites of `compile` to
expect a promise instead of the object.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-08-08 11:49:06 -04:00
Adam Wathan
d55852a17c
Update CHANGELOG.md 2024-08-08 10:05:38 -04:00
Adam Wathan
8a01fabb6d
Update CHANGELOG.md 2024-08-08 10:05:15 -04:00
Philipp Spiess
af2e69959d
Add test.debug to integration tests (#14133)
While working on #14078, there were a couple of debugging techniques
that we were using quite frequently:

- Being able to `cd` into the test setup
- Seeing the stdio and stdout data in real-time (this currently requires
us to mark a test as failing)
- Checking the exact commands that are being run

Since we naturally worked around this quite often, I decided to make
this a first-level API with the introduction of a new `test.debug` flag.
When set, it will:

- Create the test setup in the project dir within a new `.debug` folder
and won't delete it after the run. Having it in an explicit folder
allows us to easily delete it manually when we need to.
- Logs all run commands to the console (`>` for a sync call, `>&` for a
spawned process)
- Logs stdio and stderr to the console in real time.
- Run the test as `.only`

<img width="2267" alt="Screenshot 2024-08-06 at 13 19 49"
src="https://github.com/user-attachments/assets/1b204ac2-feee-489e-9cd8-edf73c0f2abd">

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-08 12:02:19 +02:00
Robin Malfait
541d84a3bb
Add @source support (#14078)
This PR is an umbrella PR where we will add support for the new
`@source` directive. This will allow you to add explicit content glob
patterns if you want to look for Tailwind classes in other files that
are not automatically detected yet.

Right now this is an addition to the existing auto content detection
that is automatically enabled in the `@tailwindcss/postcss` and
`@tailwindcss/cli` packages. The `@tailwindcss/vite` package doesn't use
the auto content detection, but uses the module graph instead.

From an API perspective there is not a lot going on. There are only a
few things that you have to know when using the `@source` directive, and
you probably already know the rules:

1. You can use multiple `@source` directives if you want.
2. The `@source` accepts a glob pattern so that you can match multiple
files at once
3. The pattern is relative to the current file you are in
4. The pattern includes all files it is matching, even git ignored files
1. The motivation for this is so that you can explicitly point to a
`node_modules` folder if you want to look at `node_modules` for whatever
reason.
6. Right now we don't support negative globs (starting with a `!`) yet,
that will be available in the near future.

Usage example:

```css
/* ./src/input.css */
@import "tailwindcss";
@source "../laravel/resources/views/**/*.blade.php";
@source "../../packages/monorepo-package/**/*.js";
```

It looks like the PR introduced a lot of changes, but this is a side
effect of all the other plumbing work we had to do to make this work.
For example:

1. We added dedicated integration tests that run on Linux and Windows in
CI (just to make sure that all the `path` logic is correct)
2. We Have to make sure that the glob patterns are always correct even
if you are using `@import` in your CSS and use `@source` in an imported
file. This is because we receive the flattened CSS contents where all
`@import`s are inlined.
3. We have to make sure that we also listen for changes in the files
that match any of these patterns and trigger a rebuild.

PRs:

- [x] https://github.com/tailwindlabs/tailwindcss/pull/14063
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14085
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14079
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14067
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14076
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14080
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14127
- [x] https://github.com/tailwindlabs/tailwindcss/pull/14135

Once all the PRs are merged, then this umbrella PR can be merged. 

> [!IMPORTANT]  
> Make sure to merge this without rebasing such that each individual PR
ends up on the main branch.

---------

Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-08-07 16:38:44 +02:00
Robin Malfait
28a5438ab4
Add inert variant (#14129)
This PR adds a new `inert` variant.

We use `:where([inert], [inert] *)`, because the element with the
`inert` attribute and any of its descendants will be inert.

For example, both these buttons will have `opacity-50`:

```html
<button inert class="inert:opacity-50">I am inert</button>
<div inert>
  <button class="inert:opacity-50">I am also inert</button>
</div>
```

See: https://play.tailwindcss.com/Jqedv6phGn
2024-08-07 16:09:01 +02:00
Philipp Spiess
8f2aa3a2b7
Error on invalid @plugin usage (#14134)
This PR just adds two minor errors to guard against invalid `@plugin`
usage similarly to what we do with `@source` in
https://github.com/tailwindlabs/tailwindcss/pull/14078.
2024-08-07 15:50:25 +02:00
Adam Wathan
e000caa0bd
Add support for inline option when defining @theme values (#14095)
This PR adds support for a new `inline` option when defining a `@theme`
block that tells Tailwind to use raw theme values for utilities instead
of referencing the corresponding generated CSS variable.

```css
/* Input */
@theme inline {
  --color-red-500: #ef4444;
  /* ... */
}


/* Example output */
:root {
  --color-red-500: #ef4444;
}

.text-red-500 {
  color: #ef4444;
}
```

This can be composed with the existing `reference` option in case you
want to define a `@theme` block as both `reference` (so the variables
aren't generated) and `inline`:

```css
/* Input */
@theme inline reference {
  --color-red-500: #ef4444;
  /* ... */
}


/* Example output */
.text-red-500 {
  color: #ef4444;
}
```

Since you can have multiple `@theme` blocks, you can even define some
values normally and some as inline based on how you're using them. For
example you might want to use `inline` for defining literal tokens like
`--color-red-500`, but include the variable for tokens that you want to
be able to theme like `--color-primary`:

```css
/* Input */
@theme inline {
  --color-red-500: #ef4444;
  /* ... */
}

@theme {
  --color-primary: var(--color-red-500);
}


/* Example output */
:root {
  --color-red-500: #ef4444;
  --color-primary: var(--color-red-500);
}

.text-red-500 {
  color: #ef4444;
}

.text-primary {
  color: var(--color-primary, var(--color-red-500));
}
```

## Breaking changes

Prior to this PR, you could `@import` a stylesheet that contained
`@theme` blocks as reference by adding the `reference` keyword to your
import:

```css
@import "./my-theme.css" reference;
```

Now that `reference` isn't the only possible option when declaring your
`@theme`, this syntax has changed to a new `theme(…)` function that
accepts `reference` and `inline` as potential space-separated values:

```css
@import "./my-theme.css";
@import "./my-theme.css" theme(reference);
@import "./my-theme.css" theme(inline);
@import "./my-theme.css" theme(reference inline);
```

If you are using the `@import … reference` option with an earlier alpha
release, you'll need to update your code to `@import … theme(reference)`
once this PR lands in a release.

## Motivation

This PR is designed to solve an issue pointed out in #14091.

Prior to this PR, generated utilities would always reference variables
directly, with the raw value as a fallback:

```css
/* Input */
@theme {
  --color-red-500: #ef4444;
  /* ... */
}


/* Example output */
:root {
  --color-red-500: #ef4444;
}

.text-red-500 {
  color: var(--color-red-500, #ef4444);
}
```

But this can create issues with variables resolving to an unexpected
value when a theme value is referencing another variable defined on
`:root`.

For example, say you have a CSS file like this:

```css
:root, .light {
  --text-fg: #000; 
}

.dark {
  --text-fg: #fff;
}

@theme {
  --color-fg: var(--text-fg);
}
```

Without `@theme inline`, we'd generate this output if you used the
`text-fg` utility:

```css
:root, .light {
  --text-fg: #000; 
}

.dark {
  --text-fg: #fff;
}

:root {
  --color-fg: var(--text-fg);
}

.text-fg {
  color: var(--color-fg, var(--text-fg));
}
```

Now if you wrote this HTML, you're probably expecting your text to be
the dark mode color:

```html
<div class="dark">
  <h1 class="text-fg">Hello world</h1>
</div>
```

But you'd actually get the light mode color because of this rule:

```css
:root {
  --color-fg: var(--text-fg);
}

.text-fg {
  color: var(--color-fg, var(--text-fg));
}
```

The browser will try to resolve the `--color-fg` variable, which is
defined on `:root`. When it tries to resolve the value, _it uses the
value of `var(--text-fg)` as it would resolve at `:root`_, not what it
would resolve to based on the element that has the `text-fg` class.

So `var(--color-fg)` resolves to `#000` because `var(--text-fg)`
resolved to `#000` at the point in the tree where the browser resolved
the value of `var(--color-fg)`.

By using `@theme inline`, the `.text-fg` class looks like this:

```css
.text-fg {
  color: var(--text-fg);
}
```

With this definition, the browser doesn't try to resolve `--color-fg` at
all and instead resolves `--text-fg` directly which correctly resolves
to `#fff` as expected.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-02 09:37:30 -04:00
Philipp Spiess
27912f9bb5
Add integration test setup and tests for the Vite integration (#14089)
This PR adds a new root `/integrations` folder that will be the home of
integration tests. The idea of these tests is to use Tailwind in various
setups just like our users would (by only using the publishable npm
builds).

To avoid issues with concurrent tests making changes to the file system,
to make it very easy to test through a range of versions, and to avoid
changing configuration objects over and over in test runs, we decided to
inline the scaffolding completely into the test file and have no
examples checked into the repo.

Here's an example of how this can look like for a simple Vite test:

```ts
test('works with production builds', {
    fs: {
      'package.json': json`
        {
          "type": "module",
          "dependencies": {
            "@tailwindcss/vite": "workspace:^",
            "tailwindcss": "workspace:^"
          },
          "devDependencies": {
            "vite": "^5.3.5"
          }
        }
      `,
      'vite.config.ts': ts`
        import tailwindcss from '@tailwindcss/vite'
        import { defineConfig } from 'vite'

        export default defineConfig({
          build: { cssMinify: false },
          plugins: [tailwindcss()],
        })
      `,
      'index.html': html`
        <head>
          <link rel="stylesheet" href="./src/index.css">
        </head>
        <body>
          <div class="underline m-2">Hello, world!</div>
        </body>
      `,
      'src/index.css': css`
        @import 'tailwindcss/theme' reference;
        @import 'tailwindcss/utilities';
      `,
    },
  },
  async ({ fs, exec }) => {
    await exec('pnpm vite build')

    expect.assertions(2)
    for (let [path, content] of await fs.glob('dist/**/*.css')) {
      expect(path).toMatch(/\.css$/)
      expect(stripTailwindComment(content)).toMatchInlineSnapshot(
        `
        ".m-2 {
          margin: var(--spacing-2, .5rem);
        }

        .underline {
          text-decoration-line: underline;
        }"
      `,
      )
    }
  },
)
```

By defining all dependencies this way, we never have to worry about
which fixtures are checked in and can more easily describe changes to
the setup.

For ergonomics, we've also added the [`embed` prettier
plugin](https://github.com/Sec-ant/prettier-plugin-embed). This will
mean that files inlined in the `fs` setup are properly indented. No
extra work needed!

If you're using VS Code, I can also recommend the [Language
Literals](https://marketplace.visualstudio.com/items?itemName=sissel.language-literals)
extension so that syntax highlighting also _just works_.

A neat feature of inlining the scaffolding like this is to make it very
simple to test through a variety of versions. For example, here's how we
can set up a test against Vite 5 and Vite 4:

```js
;['^4.5.3', '^5.3.5'].forEach(viteVersion => {
    test(`works with production builds for Vite ${viteVersion}`, {
      fs: {
        'package.json': json`
          {
            "type": "module",
            "devDependencies": {
              "vite": "${viteVersion}"
            }
          }
        `,
    async () => {
      // Do something
    },
  )
})
```

## Philosophy

Before we dive into the specifics, I want to clearly state the design
considerations we have chosen for this new test suite:

- All file mutations should be done in temp folders, nothing should ever
mess with your working directory
- Windows as a first-class citizen
- Have a clean and simple API that describes the test setup only using
public APIs
- Focus on reliability (make sure cleanup scripts work and are tolerant
to various error scenarios)
- If a user reports an issue with a specific configuration, we want to
be able to reproduce them with integration tests, no matter how obscure
the setup (this means the test need to be in control of most of the
variables)
- Tests should be reasonably fast (obviously this depends on the
integration. If we use a slow build tool, we can't magically speed it
up, but our overhead should be minimal).

## How it works

The current implementation provides a custom `test` helper function
that, when used, sets up the environment according to the configuration.
It'll create a new temporary directory and create all files, ensuring
things like proper `\r\n` line endings on Windows.

We do have to patch the `package.json` specifically, since we can not
use public versions of the tailwindcss packages as we want to be able to
test against a development build. To make this happen, every `pnpm
build` run now creates tarballs of the npm modules (that contain only
the files that would also in the published build). We then patch the
`package.json` to rewrite `workspace:^` versions to link to those
tarballs. We found this to work reliably on Windows and macOS as well as
being fast enough to not cause any issues. Furthermore we also decided
to use `pnpm` as the version manager for integration tests because of
it's global module cache (so installing `vite` is fast as soon as you
installed it once).

The test function will receive a few utilities that it can use to more
easily interact with the temp dir. One example is a `fs.glob` function
that you can use to easily find files in eventual `dist/` directories or
helpers around `spawn` and `exec` that make sure that processes are
cleaned up correctly.

Because we use tarballs from our build dependencies, working on changes
requires a workflow where you run `pnpm build` before running `pnpm
test:integrations`. However it also means we can run clients like our
CLI client with no additional overhead—just install the dependency like
any user would and set up your test cases this way.

## Test plan

This PR also includes two Vite specific integration tests: One testing a
static build (`pnpm vite build`) and one a dev mode build (`pnpm vite
dev`) that also makes changes to the file system and asserts that the
resources properly update.

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-02 11:50:49 +02:00
Philipp Spiess
266727138c
Upgrade vitest and remove bench script from CI (#14101)
This PR updates vitest to v2. The changes are mostly around using fork
instead of threads for how tests are run which should fix one of the
issues we've found.

Ever since adding the unit tests on Windows, we started seeing
occacional flags of vitest crashing with the following error:

```
 ELIFECYCLE  Command failed with exit code 3221225477.
Error: Process completed with exit code 1.
```

When reading the [v2
changelog](https://github.com/vitest-dev/vitest/releases/tag/v2.0.0) we
saw many bug fixes related to segfaulting so we believe this was the
issue.

When upgrading `vitest` alone, we got a bunch of dependency mismatches
though (specifically, vite was installed two times with different peer
dependencies for `@types/node` which causes our vite plugin's `Plugin`
type to be different from the one in the vite playground. Yikes. These
were eventually fixed by having pnpm create a new lockfile for us. So,
unfortunatly this PR also bumps a bunch of patch versions for some
transitive dependencies. Tests seem fine, though 🤞

This PR also removes the `bench` script from CI. It doesn't give us
value in its current state (since it's not reporting when performance
regresses) but added a few seconds of unnecessary overhead to each test
run.
2024-08-02 10:33:14 +02:00
Jordan Pittman
a0f8314445 Add a stub prepare-release workflow
The `workflow_dispatch` trigger will not work for v3 unless this file is present
2024-08-01 09:59:49 -04:00
Philipp Spiess
307b281578
Run CI on any PR change (#14086)
This changes the V4 CI to run on any pull request change (so an opened,
reopened, and updated PR), regardless if the PR is directed into the
`next` branch or not.

This is helpful for testing stacked PRs like:
https://github.com/tailwindlabs/tailwindcss/pull/14078
2024-07-30 13:24:15 +02:00
Philipp Spiess
e920442e49
Prefix internal modules with internal-* (#14074)
Last week we discussed bringing in some consistency for our non-public
npm packages in the repo. We discussed using custom namespaces (e.g.
`@tailwindcss-internal`) vs. simple prefixes but it does not matter too
much if we are both consistent with our pattern and it's easy for us to
see whether a plugin is public or not.

Since we have a mixture of public namespaced (`@tailwindcss/*`) and
non-namespaced (`tailwindcss`) packages, I think it would be best if we
use a prefix to signal internal dependencies. This PR proposes we use
`internal-*` as the prefix and renames `test-utils` to
`internal-example-plugin` (since, really, this package is just an
example for the Tailwind plugin system).
2024-07-29 10:58:07 -04:00
Philipp Spiess
a2159e80f5
Add Windows CI (#14065)
This PR changes the GitHub action workflow for V4 to start running all
unit tests and build on both Ubuntu (our current default) _and_ Windows.
This is to ensure we catch issues with paths and other Windows-specific
things sooner. It does, however, not replace testing on Windows.
2024-07-29 16:50:06 +02:00
Alexander Kachkaev
87c9f32cbc
Remove cursor override for :disabled buttons (#14061)
Related to https://github.com/tailwindlabs/tailwindcss/issues/8961 and
https://github.com/tailwindlabs/tailwindcss/pull/8962

Before v4, buttons got this CSS in preflight:


9824cb64a0/src/css/preflight.css (L339-L353)

v4 (`next` branch) no longer has `cursor: pointer` in
[preflight.css](2fe2499635/packages/tailwindcss/preflight.css)

This PR removes additional CSS for `:disabled` buttons. It was meant to
undo an override that is no longer present.
2024-07-29 10:10:15 -04:00
Alexander Kachkaev
0b7163c727
Specify pnpm version for corepack users (#14066) 2024-07-29 10:06:59 -04:00
Robin Malfait
2fe2499635
Fix failing publish step (#14060)
One of the (private) packages was missing a version which caused `pnpm
publish` to fail. This PR adds the missing version.
2024-07-25 17:31:52 +02:00
Adam Wathan
50a6a37dc9
Prepare for v4.0.0-alpha.18 release (#14057)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-25 10:19:13 -04:00
Adam Wathan
8eca436b3c
Reduce specificity of * variant (#14056)
This PR reduces the specificity of the * variant so that classes
directly on the child elements take precedence over the styles applied
by the parent.

Previously a utility like `*:flex` would generate this CSS:

```css
.\*\:flex > * {
  display: flex;
}
```

This selector has a specificity of `0,1,0`, which is the same as the
specificity for a bare utility class like `flex`, `block`, or `grid`.

Because variants always appear later in the CSS file than bare
utilities, this means that given this HTML, the `grid` class on the
child element would have no effect:

```html
<div class="*:flex">
  <div>...</div>
  <div class="grid">...</div>
  <div>...</div>
</div>
```

After this PR, the `*:flex` utility generates this CSS instead:

```css
:where(.\*\:flex > *) {
  display: flex;
}
```

This selector has a specificity of `0,0,0`, so even though it appears
later in the CSS, a bare utility with a specificity of `0,1,0` will
still take precedence.

This is something we wanted to do when we first introduced the `*`
variant in the v3 series, but couldn't because having such a low
specificity meant that styles in Preflight would take precedence over
utilities like `*:flex`, which is not would anyone would want.

We can make this change for v4 because now all of Preflight is wrapped
in a dedicated `@layer`, and rules from later layers always take
precedence over rules from earlier layers even if the rule in the later
layer has a lower specificity.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-25 10:09:47 -04:00
Adam Wathan
f4bb9a8df3 Tweak changelog entry 2024-07-25 10:03:29 -04:00
Philipp Spiess
d7ec082519
Update CHANGELOG.md 2024-07-25 10:14:22 +02:00
Jordan Pittman
f0e9343b5b
Add support for defining simple custom utilities in CSS via @utility (#14044)
This PR allows you to add custom utilities to your project via the new
`@utility` rule.

For example, given the following:
```css
@utility text-trim {
  text-box-trim: both;
  text-box-edge: cap alphabetic;
}
```

A new `text-trim` utility is available and can be used directly or with
variants:
```html
<div class="text-trim">...</div>
<div class="hover:text-trim">...</div>
<div class="lg:dark:text-trim">...</div>
```

If a utility is defined more than one time the latest definition will be
used:
```css
@utility text-trim {
  text-box-trim: both;
  text-box-edge: cap alphabetic;
}

@utility text-trim {
  text-box-trim: both;
  text-box-edge: cap ideographic;
}
```

Then using `text-trim` will produce the following CSS:
```css
.text-trim {
  text-box-trim: both;
  text-box-edge: cap ideographic;
}
```

You may also override specific existing utilities with this — for
example to add a `text-rendering` property to the `text-sm` utility:
```css
@utility text-sm {
  font-size: var(--font-size-sm, 0.875rem);
  line-height: var(--font-size-sm--line-height, 1.25rem);
  text-rendering: optimizeLegibility;
}
```

Though it's preferred, should you not need to add properties, to
override the theme instead.

Lastly, utilities with special characters do not need to be escaped like
you would for a class name in a selector:
```css
@utility push-1/2 {
  right: 50%;
}
```

We do however explicitly error on certain patterns that we want to
reserve for future use, for example `push-*` and `push-[15px]`.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-07-24 11:07:24 -04:00
Philipp Spiess
300524b893
Normalize attribute selectors for data-* and aria-* modifiers (#14040)
Fixes #14026 
See https://github.com/tailwindlabs/tailwindcss/pull/14037 for the v3
fix

When translating `data-` and `aria-` modifiers with attribute selectors,
we currently do not wrap the target attribute in quotes. This only works
for keywords (purely alphabetic words) but breaks as soon as there are
numbers or things like spaces in the attribute:

```html
<div data-id="foo" class="data-[id=foo]:underline">underlined</div>
<div data-id="f1" class="data-[id=1]:underline">not underlined</div>
<div data-id="foo bar" class="data-[id=foo_bar]:underline">not underlined</div>
```

Since it's fairly common to have attribute selectors with `data-` and
`aria-` modifiers, this PR will now wrap the attribute in quotes unless
these are already wrapped.

| Tailwind Modifier  | CSS Selector |
| ------------- | ------------- |
| `.data-[id=foo]`  | `[data-id='foo']`  |
| `.data-[id='foo']`  | `[data-id='foo']`  |
| `.data-[id=foo_i]`  | `[data-id='foo i']`  |
| `.data-[id='foo'_i]`  | `[data-id='foo' i]`  |
| `.data-[id=123]`  | `[data-id='123']`  |

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-07-24 16:55:07 +02:00
Jordan Pittman
6ab289343d
Throw out compound variants using variants with nested selectors (#14018) 2024-07-17 15:08:34 -04:00
Jordan Pittman
705255583c
Ensure compound variants work with variants with multiple selectors (#14016)
* Ensure compound variants work with variants with multiple selectors

* Update changelog
2024-07-17 15:03:57 -04:00
Jordan Pittman
e8546df800
Don’t allow at-rule-only variants to be compounded (#14015)
* Don’t allow at-rule-only variants to be compounded

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-17 14:52:29 -04:00
Jordan Pittman
cf846a5ff6 Ensure nested selectors are not modified when using group-* and peer-*
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-07-16 17:41:43 -04:00
Jordan Pittman
23e6d433a2
Allow variants to be overridden (#14008)
* Allow variants to be overridden

* Update changelog

* Update changelog

* Update tests
2024-07-16 16:55:13 -04:00
Robin Malfait
5ebd5896d7
Add support for custom variants via CSS (#13992)
* implement `@variant` in CSS

* implement `addVariant(name, objectTree)`

* update changelog

* ensure that `@variant` can only be used top-level

* simplify Plugin API type

* Use type instead of interface (for now)

* Use more realistic variant for test

* Allow custom properties to use `@slot` as content

* Use "cannot" instead of "can not"

* Remove `@variant` right away

* Throw when `@variant` is missing a selector or body

* Use "CSS-in-JS" terminology instead of "CSS Tree"

* Rename tests

* Mark some tests that seem wrong

* Tweak comment, remove unnecessary return

* Ensure group is usable with custom selector lists

* Only apply extra `:is(…)` when there are multiple selectors

* Tweak comment

* Throw when @variant has both selector and body

* Rework tests to use more realistic examples

* Compound variants on an isolated copy

This prevents traversals from leaking across variants

* Handle selector lists for peer variants

* Ignore at rules when compounding group and peer variants

* Re-enable skipped tests

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-07-16 16:23:23 -04:00
Adam Wathan
54474086c8
Add support for basic addVariant plugins with new @plugin directive (#13982)
* Add basic `addVariant` plugin support

* Return early

* Load plugins right away instead later

* Use correct type for variant name

* Preliminary support for addVariant plugins in PostCSS plugin

* Add test for compounding plugin variants

* Add basic `loadPlugin` support to Vite plugin

* Add basic `loadPlugin` support to CLI

* add `io.ts` for integrations

* use shared `loadPlugin` from `tailwindcss/io`

* add `tailwindcss-test-utils` to `@tailwindcss/cli` and `@tailwindcss/vite`

* only add `tailwindcss-test-utils` to `tailwindcss` as a dev dependency

Because `src/io.ts` is requiring the plugin.

* move `tailwindcss-test-utils` to `@tailwindcss/postcss `

This is the spot where we actually need it.

* use newer pnpm version

* Duplicate loadPlugin implementation instead of exporting io file

* Remove another io reference

* update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-07-11 09:47:26 -04:00
Robin Malfait
f7686e1982
Add missing utilities that exist in v3 (#13971)
* replace `resize-both` with `resize`

* add missing `fill-none`

* add missing `accent-auto`

* add missing `blur-0` and `backdrop-blur-0`

We already have `blur-none`, but that sets the blur to `' '`, whereas
`blur-0` sets it to `blur(0)`.

* add missing `drop-shadow-none`

* support negative `hue-rotate` utilities

* support negative `backdrop-hue-rotate` utilities

* add missing `max-w-screen-*` utilities

* update changelog

* Revert "add missing `blur-0` and `backdrop-blur-0`"

This reverts commit 7c42e4e25d3c06b312107afb5325df4b452086a6.

* Revert "add missing `max-w-screen-*` utilities"

This reverts commit 0c68e890ccfb68d104b252bdb3a8a2b2c34a0793.
2024-07-10 16:05:16 +02:00
Robin Malfait
6c0c6a5941
Discard invalid variants and utilities with modifiers (#13977)
* ensure that static utilities do not take a `modifier`

* do not allow multiple segments for now

Right now, `bg-red-1/2/3` should not parse

* add tests for variants that don't accept a modifier

* ensure static variants do not accept a modifier

* do not accept a modifier for some variants

* add tests for utilities that don't accept a modifier

* do not accept a modifier for some utilities

* update changelog

* re-add sorting related test
2024-07-10 15:56:33 +02:00
Robin Malfait
de48a76b6d
Ensure opacity modifier with variables work with color-mix() (#13972)
* ensure opacity modifier variables work as expected

We use `color-mix()` in v4 which means that we can use this for the
opacity modifier. One thing we do already is convert values such as
`0.5` to `50%` because that's what the `color-mix()` function expects.

However, if you use a variable like this:

```html
<div class="[--opacity:0.5] bg-red-500/[var(--opacity)]"></div>
```

This currently generates:

```css
.bg-red-500\/\[var\(--opacity\)\] {
  background-color: color-mix(
    in srgb,
    var(--color-red-500, #ef4444) var(--opacity),
    transparent
  );
}
.\[--opacity\:0\.5\] {
  --opacity: 0.5;
}
```

Which won't work because the opacity variable resolves to `0.5` instead
of the expected`50%`.

This commit fixes that by always ensuring that we use `* 100%`.

- If you already had a percentage, we would have `calc(50% * 100%)`
  which is `50%`.
- If we have `0.5` then we would have `calc(0.5 * 100%)` which is also
  `50%`.

* wrap everything but percentages in `calc(… * 100%)`

* use `else if`

* update changelog
2024-07-10 15:52:05 +02:00
Robin Malfait
992cf8d573
Fix parsing body-less at-rule without terminating semicolon (#13978)
* ensure body-less at-rules without semicolon are parsed correctly

* update changelog
2024-07-10 15:44:28 +02:00
Robin Malfait
8e97a48357
Discard invalid classes such as bg-red-[#000] (#13970)
* add test that verifies that parsing `bg-red-[#0088cc]` should not work

* improve parsing of arbitrary values, root is known

When using arbitrary values such as `bg-[#0088cc]` then we know that
everything before the `-[` part is the `root` of the utility. This also
means that this should exist in the design system as-is.

If we use `findRoot` instead, it means that `bg-red-[#0088cc]` would
also just parse fine and we don't want.

* small refactor: define `important` and `negative` directly

It's not necessary to track state in a state object. Let's use the
variables directly.

* small refactor: use return on same line for consistency

* add test that verifies that parsing `bg-` should not work

* move `value === ''` check up

The value doesn't change anymore, which means we can discard early and
don't need to start creating candidate objects.

* adjust comment with example

* update changelog
2024-07-10 10:01:23 +02:00
Robin Malfait
06e96e0767
Prep next release: 4.0.0-alpha.17 (#13951)
* bump to version `4.0.0-alpha.17`

* update changelog
2024-07-04 19:08:10 +02:00
Benoît Rouleau
3b85780f89
Revert “Prevent Preflight from affecting list semantics” (#13907)
Due to difference in how it handles an empty `<li>`: https://codepen.io/benface/pen/MWdRdyY
2024-07-04 11:21:09 -04:00
Adam Wathan
407de01e8d
Use initial for @property fallbacks instead of (#13949)
* Use `initial` for `@property` fallbacks instead of ` `

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-04 11:20:05 -04:00
Adam Wathan
62de02a379
Support combining arbitrary shadows without a color with shadow color utilities (#13876)
* Support combining arbitrary shadows without a color with shadow color utilities

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-06-21 17:36:59 -04:00
Benoît Rouleau
332347ed83
Prevent Preflight from affecting list semantics (#13815)
* Prevent Preflight from affecting list semantics

* Use `list-style` property

* Update snapshots

* Update changelog

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-06-14 15:52:50 -04:00
Jordan Pittman
d9cd199aa6 Fix spacing 2024-06-14 12:05:15 -04:00
Jordan Pittman
2e1e1673f0 Update changelog 2024-06-14 09:42:05 -04:00