No description
Find a file
Robin Malfait d14249ddc2
Add CSS codemods for migrating @layer utilities (#14455)
This PR adds CSS codemods for migrating existing `@layer utilities` to
`@utility` directives.

This PR has the ability to migrate the following cases:

---

The most basic case is when you want to migrate a simple class to a
utility directive.

Input:
```css
@layer utilities {
  .foo {
    color: red;
  }

  .bar {
    color: blue;
  }
}
```

Output:
```css
@utility foo {
  color: red;
}

@utility bar {
  color: blue;
}
```

You'll notice that the class `foo` will be used as the utility name, the
declarations (and the rest of the body of the rule) will become the body
of the `@utility` definition.

---

In v3, every class in a selector will become a utility. To correctly
migrate this to `@utility` directives, we have to register each class in
the selector and generate `n` utilities.

We can use nesting syntax, and replace the current class with `&` to
ensure that the final result behaves the same.

Input:
```css
@layer utilities {
  .foo .bar .baz {
    color: red;
  }
}
```

Output:
```css
@utility foo {
  & .bar .baz {
    color: red;
  }
}

@utility bar {
  .foo & .baz {
    color: red;
  }
}

@utility .baz {
  .foo .bar & {
    color: red;
  }
}
```

In this case, it could be that you know that some of them will never be
used as a utility (e.g.: `hover:bar`), but then you can safely remove
them.

---

Even classes inside of `:has(…)` will become a utility. The only
exception to the rule is that we don't do it for `:not(…)`.

Input:
```css
@layer utilities {
  .foo .bar:not(.qux):has(.baz) {
    display: none;
  }
}
```

Output:
```css
@utility foo {
  & .bar:not(.qux):has(.baz) {
    display: none;
  }
}

@utility bar {
  .foo &:not(.qux):has(.baz) {
    display: none;
  }
}

@utility baz {
  .foo .bar:not(.qux):has(&) {
    display: none;
  }
}
```

Notice that there is no `@utility qux` because it was used inside of
`:not(…)`.

---

When classes are nested inside at-rules, then these classes will also
become utilities. However, the `@utility <name>` will be at the top and
the at-rules will live inside of it. If there are multiple classes
inside a shared at-rule, then the at-rule will be duplicated for each
class.

Let's look at an example to make it more clear:

Input:
```css
@layer utilities {
  @media (min-width: 640px) {
    .foo {
      color: red;
    }

    .bar {
      color: blue;
    }

    @media (min-width: 1024px) {
      .baz {
        color: green;
      }

      @media (min-width: 1280px) {
        .qux {
          color: yellow;
        }
      }
    }
  }
}
```

Output:
```css
@utility foo {
  @media (min-width: 640px) {
    color: red;
  }
}

@utility bar {
  @media (min-width: 640px) {
    color: blue;
  }
}

@utility baz {
  @media (min-width: 640px) {
    @media (min-width: 1024px) {
      color: green;
    }
  }
}

@utility qux {
  @media (min-width: 640px) {
    @media (min-width: 1024px) {
      @media (min-width: 1280px) {
        color: yellow;
      }
    }
  }
}
```

---

When classes result in multiple `@utility` directives with the same
name, then the definitions will be merged together.

Input:
```css
@layer utilities {
  .no-scrollbar::-webkit-scrollbar {
    display: none;
  }

  .no-scrollbar {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
}
```

Intermediate representation:
```css
@utility no-scrollbar {
  &::-webkit-scrollbar {
    display: none;
  }
}

@utility no-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
```

Output:
```css
@utility no-scrollbar {
  &::-webkit-scrollbar {
    display: none;
  }
  -ms-overflow-style: none;
  scrollbar-width: none
}
```

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-09-24 18:17:09 +02:00
.github ci: speedup windows integrations tests (#14485) 2024-09-20 15:59:18 -04:00
crates Release v4.0.0-alpha.24 (#14395) 2024-09-12 16:10:56 +02:00
integrations Add CSS codemods for migrating @layer utilities (#14455) 2024-09-24 18:17:09 +02:00
packages Add CSS codemods for migrating @layer utilities (#14455) 2024-09-24 18:17:09 +02:00
patches Add standalone CLI (#14270) 2024-09-02 15:23:46 +02:00
playgrounds Postcss: Bring back proper type exports (#14256) 2024-08-26 15:54:07 +02:00
scripts Add GitHub release workflow (#14346) 2024-09-05 09:45:29 -04:00
.gitattributes Add .gitattributes and define a merge strategy for changelog files 2024-08-26 16:27:41 +02:00
.gitignore Add test.debug to integration tests (#14133) 2024-08-08 12:02:19 +02:00
.npmrc introduce v4 codebase 2024-03-05 14:29:15 +01:00
.prettierignore Hoist oxide/crates to just crates (#13333) 2024-03-23 09:00:48 -04:00
Cargo.lock Improve Oxide scanner API (#14187) 2024-08-16 15:05:42 +02:00
Cargo.toml Hoist oxide/crates to just crates (#13333) 2024-03-23 09:00:48 -04:00
CHANGELOG.md Add CSS codemods for migrating @layer utilities (#14455) 2024-09-24 18:17:09 +02:00
LICENSE Add README, LICENSE, and CONTRIBUTING (#13088) 2024-03-05 14:45:39 -05:00
package.json Update turbo 2.0.12 → 2.1.1 (minor) (#14456) 2024-09-23 14:24:09 +02:00
pnpm-lock.yaml Add CSS codemods for migrating @layer utilities (#14455) 2024-09-24 18:17:09 +02:00
pnpm-workspace.yaml Bump dependencies (#14160) 2024-08-09 16:12:24 +02:00
README.md Copy README file to every package (#13096) 2024-03-06 08:49:31 -05:00
rust-toolchain.toml Pin rust toolchain to work around Windows regression (#14406) 2024-09-12 14:07:43 +02:00
turbo.json Fix Rust build by passing through RUSTUP_HOME variable (#14171) 2024-08-12 11:37:45 +02:00
vitest.workspace.ts introduce v4 codebase 2024-03-05 14:29:15 +01:00

Tailwind CSS

A utility-first CSS framework for rapidly building custom user interfaces.

Build Status Total Downloads Latest Release License


Documentation

For full documentation, visit tailwindcss.com.

Community

For help, discussion about best practices, or any other conversation that would benefit from being searchable:

Discuss Tailwind CSS on GitHub

For chatting with others using the framework:

Join the Tailwind CSS Discord Server

Contributing

If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.