diff --git a/.github/workflows/release-insiders.yml b/.github/workflows/release-insiders.yml index 4a91bf2..e0ddd7e 100644 --- a/.github/workflows/release-insiders.yml +++ b/.github/workflows/release-insiders.yml @@ -4,6 +4,10 @@ on: push: branches: [main] +permissions: + contents: read + id-token: write + jobs: build: runs-on: ubuntu-latest @@ -45,6 +49,6 @@ jobs: run: npm version 0.0.0-insiders.${{ env.SHA_SHORT }} --force --no-git-tag-version - name: Publish - run: npm publish --tag insiders + run: npm publish --provenance --tag insiders env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2b133f8..7108a9a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,7 @@ on: permissions: contents: read + id-token: write jobs: build: @@ -44,6 +45,6 @@ jobs: echo "RELEASE_CHANNEL=$(npm run release-channel --silent)" >> $GITHUB_ENV - name: Publish - run: npm publish --tag ${{ env.RELEASE_CHANNEL }} + run: npm publish --provenance --tag ${{ env.RELEASE_CHANNEL }} env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f5f9341 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Tailwind Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 634ca32..fa38a2b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +> [!NOTE] +> As of Tailwind CSS v4.0, container queries are supported in the framework by default and this plugin is no longer required. + # @tailwindcss/container-queries A plugin for Tailwind CSS v3.2+ that provides utilities for container queries. @@ -7,7 +10,7 @@ A plugin for Tailwind CSS v3.2+ that provides utilities for container queries. Install the plugin from npm: ```sh -npm install @tailwindcss/container-queries +npm install -D @tailwindcss/container-queries ``` Then add the plugin to your `tailwind.config.js` file: @@ -58,7 +61,7 @@ In addition to using one of the [container sizes](#configuration) provided by de ```html
-
+
@@ -72,23 +75,36 @@ To stop an element from acting as a container, use the `@container-normal` class +### With a prefix + +If you have configured Tailwind to use a prefix, make sure to prefix both the `@container` class and any classes where you are using a container query modifier: + +```html +
+ +
+ +
+
+``` + ## Configuration By default we ship with the following configured values: -| Name | CSS | -| ------ | ------------------------------- | -| `@xs` | `@container (min-width: 20rem)` | -| `@sm` | `@container (min-width: 24rem)` | -| `@md` | `@container (min-width: 28rem)` | -| `@lg` | `@container (min-width: 32rem)` | -| `@xl` | `@container (min-width: 36rem)` | -| `@2xl` | `@container (min-width: 42rem)` | -| `@3xl` | `@container (min-width: 48rem)` | -| `@4xl` | `@container (min-width: 56rem)` | -| `@5xl` | `@container (min-width: 64rem)` | -| `@6xl` | `@container (min-width: 72rem)` | -| `@7xl` | `@container (min-width: 80rem)` | +| Name | CSS | +| ------ | -------------------------------------------- | +| `@xs` | `@container (min-width: 20rem /* 320px */)` | +| `@sm` | `@container (min-width: 24rem /* 384px */)` | +| `@md` | `@container (min-width: 28rem /* 448px */)` | +| `@lg` | `@container (min-width: 32rem /* 512px */)` | +| `@xl` | `@container (min-width: 36rem /* 576px */)` | +| `@2xl` | `@container (min-width: 42rem /* 672px */)` | +| `@3xl` | `@container (min-width: 48rem /* 768px */)` | +| `@4xl` | `@container (min-width: 56rem /* 896px */)` | +| `@5xl` | `@container (min-width: 64rem /* 1024px */)` | +| `@6xl` | `@container (min-width: 72rem /* 1152px */)` | +| `@7xl` | `@container (min-width: 80rem /* 1280px */)` | You can configure which values are available for this plugin under the `containers` key in your `tailwind.config.js` file: diff --git a/jest/custom-matchers.js b/jest/custom-matchers.js index 385faf7..1c62850 100644 --- a/jest/custom-matchers.js +++ b/jest/custom-matchers.js @@ -107,6 +107,11 @@ expect.extend({ printWidth: 100, }) } + + function stripped(str) { + return str.replace(/\/\* ! tailwindcss .* \*\//, '').replace(/\s/g, '').replace(/;/g, '') + } + const options = { comment: 'stripped(received) === stripped(argument)', isNot: this.isNot, @@ -116,7 +121,7 @@ expect.extend({ let formattedReceived = format(received) let formattedArgument = format(argument) - const pass = formattedReceived === formattedArgument + const pass = stripped(formattedReceived) === stripped(formattedArgument) const message = pass ? () => { diff --git a/package.json b/package.json index 6b08cb7..4d103fb 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "jest": "^29.1.2", "postcss": "^8.4.17", "prettier": "^2.7.1", - "tailwindcss": "0.0.0-insiders.3011f46", + "tailwindcss": "0.0.0-insiders.7385373", "typescript": "^4.8.4" } } diff --git a/tests/index.test.ts b/tests/index.test.ts index 077b628..8e1f82f 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -7,7 +7,7 @@ it('container queries', () => { { raw: html`
@@ -54,111 +54,113 @@ it('container queries', () => { container-type: inline-size; } + .\@container-\[size\] { + container-type: size; + } + + .\@container-\[size\]\/sidebar { + container: sidebar / size; + } + .\@container-normal { container-type: normal; } - .\@container\/sidebar { - container-type: inline-size; - container-name: sidebar; + .\@container-normal\/sidebar { + container: sidebar; } - .\@container-normal\/sidebar { - container-type: normal; - container-name: sidebar; + .\@container\/sidebar { + container: sidebar / inline-size; } - @container (min-width: 123px) { + @container (width >= 123px) { .\@\[123px\]\:underline { text-decoration-line: underline; } } - @container (min-width: 200rem) { + @container (width >= 200rem) { .\@\[200rem\]\:underline { text-decoration-line: underline; } } - @container (min-width: 312px) { + @container (width >= 312px) { .\@\[312px\]\:underline { text-decoration-line: underline; } } - @container container1 (min-width: 320px) { + @container container1 (width >= 320px) { .\@sm\/container1\:underline { text-decoration-line: underline; } } - @container container2 (min-width: 320px) { + @container container2 (width >= 320px) { .\@sm\/container2\:underline { text-decoration-line: underline; } } - @container container10 (min-width: 320px) { + @container container10 (width >= 320px) { .\@sm\/container10\:underline { text-decoration-line: underline; } } - @container (min-width: 320px) { + @container (width >= 320px) { .\@sm\:underline { text-decoration-line: underline; } } - @container container1 (min-width: 768px) { + @container container1 (width >= 768px) { .\@md\/container1\:underline { text-decoration-line: underline; } } - @container container2 (min-width: 768px) { + @container container2 (width >= 768px) { .\@md\/container2\:underline { text-decoration-line: underline; } } - @container container10 (min-width: 768px) { + @container container10 (width >= 768px) { .\@md\/container10\:underline { text-decoration-line: underline; } } - @container (min-width: 768px) { + @container (width >= 768px) { .\@md\:underline { text-decoration-line: underline; } } - @container container1 (min-width: 1024px) { - .\@lg\/container1\:underline { - text-decoration-line: underline; - } + @container container1 (width >= 1024px) { + .\@lg\/container1\:underline, .\@\[1024px\]\/container1\:underline { text-decoration-line: underline; } } - @container container2 (min-width: 1024px) { + @container container2 (width >= 1024px) { .\@lg\/container2\:underline { text-decoration-line: underline; } } - @container container10 (min-width: 1024px) { + @container container10 (width >= 1024px) { .\@lg\/container10\:underline { text-decoration-line: underline; } } - @container (min-width: 1024px) { - .\@lg\:underline { - text-decoration-line: underline; - } + @container (width >= 1024px) { + .\@lg\:underline, .\@\[1024px\]\:underline { text-decoration-line: underline; } @@ -195,49 +197,49 @@ it('should be possible to use default container queries', () => { return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - @container (min-width: 20rem) { + @container (width >= 20rem) { .\@xs\:underline { text-decoration-line: underline; } } - @container (min-width: 24rem) { + @container (width >= 24rem) { .\@sm\:underline { text-decoration-line: underline; } } - @container (min-width: 28rem) { + @container (width >= 28rem) { .\@md\:underline { text-decoration-line: underline; } } - @container (min-width: 32rem) { + @container (width >= 32rem) { .\@lg\:underline { text-decoration-line: underline; } } - @container (min-width: 48rem) { + @container (width >= 48rem) { .\@3xl\:underline { text-decoration-line: underline; } } - @container (min-width: 64rem) { + @container (width >= 64rem) { .\@5xl\:underline { text-decoration-line: underline; } } - @container (min-width: 72rem) { + @container (width >= 72rem) { .\@6xl\:underline { text-decoration-line: underline; } } - @container (min-width: 80rem) { + @container (width >= 80rem) { .\@7xl\:underline { text-decoration-line: underline; }