diff --git a/.github/workflows/release-insiders.yml b/.github/workflows/release-insiders.yml new file mode 100644 index 0000000..2d77e8e --- /dev/null +++ b/.github/workflows/release-insiders.yml @@ -0,0 +1,54 @@ +name: Release Insiders + +on: + push: + branches: [master] + +permissions: + contents: read + id-token: write + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [12] + + steps: + - uses: actions/checkout@v2 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + registry-url: 'https://registry.npmjs.org' + + - name: Use cached node_modules + id: cache + uses: actions/cache@v2 + with: + path: node_modules + key: nodeModules-${{ hashFiles('**/package-lock.json') }}-${{ matrix.node-version }} + restore-keys: | + nodeModules- + + - name: Install dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: npm install + env: + CI: true + + - name: Resolve version + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + + - name: 'Version based on commit: 0.0.0-insiders.${{ steps.vars.outputs.sha_short }}' + run: npm version 0.0.0-insiders.${{ steps.vars.outputs.sha_short }} --force --no-git-tag-version + + - name: Publish + run: npm publish --provenance --tag insiders + env: + CI: true + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index daf2051..03eee30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Nothing yet! +## [0.4.2] - 2022-09-02 + +### Fixed + +- Update TypeScript types ([#34](https://github.com/tailwindlabs/tailwindcss-aspect-ratio/pull/34)) + +## [0.4.1] - 2022-09-01 + +### Added + +- Remove `dist` folder and related dependencies ([#29](https://github.com/tailwindlabs/tailwindcss-aspect-ratio/pull/29)) +- Add typescript types ([#33](https://github.com/tailwindlabs/tailwindcss-aspect-ratio/pull/33)) + +## [0.4.0] - 2021-12-09 + +### Added + +- Make sure that Tailwind CSS v3 is in peerDependencies ([ae97a25](https://github.com/tailwindlabs/tailwindcss-aspect-ratio/commit/ae97a25)) + +## [0.3.0] - 2021-10-05 + +### Added + +- Support arbitrary values in Tailwind CSS v3.0.0-alpha.1, via the new `matchComponents` API + +## [0.2.2] - 2021-10-02 + +### Fixed + +- Fix compatibility with Tailwind CSS v3.0.0-alpha.1 + ## [0.2.1] - 2021-05-24 ### Fixed @@ -49,7 +80,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Initial release! -[unreleased]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.2.1...HEAD +[unreleased]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.4.2...HEAD +[0.4.2]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.4.1...v0.4.2 +[0.4.1]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.4.0...v0.4.1 +[0.4.0]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.3.0...v0.4.0 +[0.3.0]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.2.2...v0.3.0 +[0.2.2]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.2.1...v0.2.2 [0.2.1]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.1.4...v0.2.0 [0.1.4]: https://github.com/tailwindlabs/tailwindcss-aspect-ratio/compare/v0.1.3...v0.1.4 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9ed6725 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 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 fdd0713..338e047 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,10 @@ A plugin that provides a composable API for giving elements a fixed aspect ratio Install the plugin from npm: ```sh -# Using npm -npm install @tailwindcss/aspect-ratio - -# Using Yarn -yarn add @tailwindcss/aspect-ratio +npm install -D @tailwindcss/aspect-ratio ``` -Then add the plugin to your `tailwind.config.js` file: +Then add the plugin to your `tailwind.config.js` file, and disable the `aspectRatio` core plugin to avoid conflicts with the native `aspect-ratio` utilities included in Tailwind CSS v3.0: ```js // tailwind.config.js @@ -23,6 +19,9 @@ module.exports = { theme: { // ... }, + corePlugins: { + aspectRatio: false, + }, plugins: [ require('@tailwindcss/aspect-ratio'), // ... @@ -101,3 +100,42 @@ module.exports = { } } ``` + +## Compatibility with default aspect-ratio utilities + +Tailwind CSS v3.0 shipped with [native aspect-ratio](https://tailwindcss.com/docs/aspect-ratio) support, and while these new utilities are great, the `aspect-ratio` property isn't supported in Safari 14, which still has [significant global usage](https://caniuse.com/mdn-css_properties_aspect-ratio). If you need to support Safari 14, this plugin is still the best way to do that. + +While it's technically possible to use the new native `aspect-ratio` utilities as well as this plugin in the same project, it doesn't really make a lot of sense to do so. If you're able to use the new native aspect-ratio utilities, just use them instead of this plugin, as they are a lot simpler and work much better. + +However, if you do want to use both approaches in your project, maybe as a way of transitioning slowly from the plugin approach to the new native utilities, you'll need to add the following values to your `tailwind.config.js` file: + +```js +module.exports = { + // ... + theme: { + aspectRatio: { + auto: 'auto', + square: '1 / 1', + video: '16 / 9', + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + 7: '7', + 8: '8', + 9: '9', + 10: '10', + 11: '11', + 12: '12', + 13: '13', + 14: '14', + 15: '15', + 16: '16', + }, + }, +} +``` + +This is necessary, as the default `aspectRatio` values are overwritten by this plugin's values. diff --git a/dist/.gitignore b/dist/.gitignore deleted file mode 100644 index 2f41fac..0000000 --- a/dist/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!.gitignore -!.npmignore diff --git a/dist/.npmignore b/dist/.npmignore deleted file mode 100644 index e69de29..0000000 diff --git a/package.json b/package.json index 9afce62..f9fab69 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "name": "@tailwindcss/aspect-ratio", - "version": "0.2.1", + "version": "0.4.2", "main": "src/index.js", + "types": "src/index.d.ts", "license": "MIT", "repository": "https://github.com/tailwindlabs/tailwindcss-aspect-ratio", "publishConfig": { @@ -14,15 +15,15 @@ "trailingComma": "es5" }, "scripts": { - "prepublishOnly": "node scripts/build.js" + "test": "jest" }, "peerDependencies": { - "tailwindcss": ">=2.0.0" + "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" }, "devDependencies": { - "autoprefixer": "10", - "clean-css": "^4.2.1", + "jest": "^27.2.4", "postcss": "^8.2.4", - "tailwindcss": "^2.0.2" + "tailwindcss": "^3.0.0", + "tailwindcss-v2": "npm:tailwindcss@^2.2.16" } } diff --git a/scripts/build.js b/scripts/build.js deleted file mode 100644 index 8ee5212..0000000 --- a/scripts/build.js +++ /dev/null @@ -1,36 +0,0 @@ -const fs = require('fs') -const postcss = require('postcss') -const tailwind = require('tailwindcss') -const CleanCSS = require('clean-css') - -function buildDistFile(filename) { - return postcss([ - tailwind({ - corePlugins: false, - plugins: [require('../src/index.js')], - }), - require('autoprefixer'), - ]) - .process('@tailwind components', { - from: null, - to: `./dist/${filename}.css`, - map: false, - }) - .then((result) => { - fs.writeFileSync(`./dist/${filename}.css`, result.css) - return result - }) - .then((result) => { - const minified = new CleanCSS().minify(result.css) - fs.writeFileSync(`./dist/${filename}.min.css`, minified.styles) - }) - .catch((error) => { - console.log(error) - }) -} - -console.info('Building CSS...') - -Promise.all([buildDistFile('aspect-ratio')]).then(() => { - console.log('Finished building CSS.') -}) diff --git a/src/index.d.ts b/src/index.d.ts new file mode 100644 index 0000000..c23a9a3 --- /dev/null +++ b/src/index.d.ts @@ -0,0 +1,2 @@ +declare const plugin: { handler: () => void } +export = plugin diff --git a/src/index.js b/src/index.js index 572fefb..a217a70 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,62 @@ const plugin = require('tailwindcss/plugin') +const baseStyles = { + position: 'relative', + paddingBottom: `calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%)`, +} + +const childStyles = { + position: 'absolute', + height: '100%', + width: '100%', + top: '0', + right: '0', + bottom: '0', + left: '0', +} + +const noneComponent = { + '.aspect-none': { + position: 'static', + paddingBottom: '0', + }, + '.aspect-none > *': { + position: 'static', + height: 'auto', + width: 'auto', + top: 'auto', + right: 'auto', + bottom: 'auto', + left: 'auto', + }, +} + const aspectRatio = plugin( - function ({ addComponents, theme, variants, e }) { + function ({ addComponents, matchComponents, theme, variants, e }) { const values = theme('aspectRatio') + if (matchComponents) { + matchComponents( + { + 'aspect-w': (value) => [ + { + ...baseStyles, + '--tw-aspect-w': value, + }, + { + '> *': childStyles, + }, + ], + 'aspect-h': (value) => ({ '--tw-aspect-h': value }), + }, + { values } + ) + + addComponents(noneComponent) + + return + } + const baseSelectors = Object.entries(values) .map(([key, value]) => { return `.${e(`aspect-w-${key}`)}` @@ -19,33 +72,10 @@ const aspectRatio = plugin( addComponents( [ { - [baseSelectors]: { - position: 'relative', - paddingBottom: `calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%)`, - }, - [childSelectors]: { - position: 'absolute', - height: '100%', - width: '100%', - top: '0', - right: '0', - bottom: '0', - left: '0', - }, - '.aspect-none': { - position: 'static', - paddingBottom: '0', - }, - '.aspect-none > *': { - position: 'static', - height: 'auto', - width: 'auto', - top: 'auto', - right: 'auto', - bottom: 'auto', - left: 'auto', - }, + [baseSelectors]: baseStyles, + [childSelectors]: childStyles, }, + noneComponent, Object.entries(values).map(([key, value]) => { return { [`.${e(`aspect-w-${key}`)}`]: { diff --git a/tests/test.js b/tests/test.js new file mode 100644 index 0000000..0142395 --- /dev/null +++ b/tests/test.js @@ -0,0 +1,157 @@ +const postcss = require('postcss') + +let expectedV3 = ` +.aspect-w-1 { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: 1 +} +.aspect-w-1 > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-w-2 { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: 2 +} +.aspect-w-2 > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-h-2 { + --tw-aspect-h: 2 +} +.aspect-w-\\[123\\] { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: 123 +} +.aspect-w-\\[123\\] > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-w-\\[var\\(--width\\)\\] { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: var(--width) +} +.aspect-w-\\[var\\(--width\\)\\] > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-h-\\[123\\] { + --tw-aspect-h: 123 +} +.aspect-h-\\[var\\(--height\\)\\] { + --tw-aspect-h: var(--height) +} +.aspect-none { + position: static; + padding-bottom: 0 +} +.aspect-none > * { + position: static; + height: auto; + width: auto; + top: auto; + right: auto; + bottom: auto; + left: auto +} +` + +it('v3', () => { + let css = postcss([ + require('tailwindcss')({ + content: [ + { + raw: 'aspect-none aspect-w-1 aspect-w-2 aspect-h-2 aspect-w-[123] aspect-w-[var(--width)] aspect-h-[123] aspect-h-[var(--height)]', + }, + ], + plugins: [require('../')], + }), + ]).process('@tailwind components').css + + expect(css).toBe(expectedV3.trim()) +}) + +let expectedV2 = ` +.aspect-w-1, +.aspect-w-2 { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%) +} + +.aspect-w-1 > *, +.aspect-w-2 > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} + +.aspect-none { + position: static; + padding-bottom: 0 +} + +.aspect-none > * { + position: static; + height: auto; + width: auto; + top: auto; + right: auto; + bottom: auto; + left: auto +} + +.aspect-w-1 { + --tw-aspect-w: 1 +} + +.aspect-w-2 { + --tw-aspect-w: 2 +} + +.aspect-h-2 { + --tw-aspect-h: 2 +} +` + +it('v2', () => { + postcss([ + require('tailwindcss-v2')({ + purge: { enabled: true, content: [{ raw: 'aspect-none aspect-w-1 aspect-w-2 aspect-h-2' }] }, + variants: [], + plugins: [require('../')], + }), + ]) + .process('@tailwind components', { from: undefined }) + .then(({ css }) => { + expect(css).toBe(expectedV2.trim()) + }) +})