summaryrefslogtreecommitdiff
path: root/node_modules/postcss-clamp
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/postcss-clamp')
-rw-r--r--node_modules/postcss-clamp/INSTALL.md162
-rw-r--r--node_modules/postcss-clamp/LICENSE21
-rw-r--r--node_modules/postcss-clamp/README.md118
-rw-r--r--node_modules/postcss-clamp/index.js126
-rw-r--r--node_modules/postcss-clamp/index.test.js221
-rw-r--r--node_modules/postcss-clamp/package.json26
6 files changed, 674 insertions, 0 deletions
diff --git a/node_modules/postcss-clamp/INSTALL.md b/node_modules/postcss-clamp/INSTALL.md
new file mode 100644
index 00000000..f9acbee6
--- /dev/null
+++ b/node_modules/postcss-clamp/INSTALL.md
@@ -0,0 +1,162 @@
+# Installing PostCSS Clamp
+
+[PostCSS Clamp] runs in all Node environments, with special instructions for:
+
+| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) |
+| --- | --- | --- | --- | --- | --- |
+
+## Node
+
+Add [PostCSS Clamp] to your project:
+
+```bash
+$ npm install postcss-clamp --save-dev
+```
+
+Use [PostCSS Clamp] as a [PostCSS] plugin:
+
+```js
+const postcss = require('postcss');
+const postcssClamp = require('postcss-clamp');
+
+postcss([
+ postcssClamp(/* pluginOptions */)
+]).process(YOUR_CSS /*, processOptions */);
+```
+
+## PostCSS CLI
+
+Add [PostCSS CLI] to your project:
+
+```bash
+npm install postcss-cli --save-dev
+```
+
+Use **PostCSS Clamp** in your `postcss.config.js` configuration file:
+
+```js
+const postcssClamp = require('postcss-clamp');
+
+module.exports = {
+ plugins: [
+ postcssClamp(/* pluginOptions */)
+ ]
+}
+```
+
+## Webpack
+
+Add [PostCSS Loader] to your project:
+
+```bash
+npm install postcss-loader --save-dev
+```
+
+Use **PostCSS Clamp** in your Webpack configuration:
+
+```js
+const postcssClamp = require('postcss-clamp');
+
+module.exports = {
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ use: [
+ 'style-loader',
+ { loader: 'css-loader', options: { importLoaders: 1 } },
+ { loader: 'postcss-loader', options: {
+ ident: 'postcss',
+ plugins: () => [
+ postcssClamp(/* pluginOptions */)
+ ]
+ } }
+ ]
+ }
+ ]
+ }
+}
+```
+
+## Create React App
+
+Add [React App Rewired] and [React App Rewire PostCSS] to your project:
+
+```bash
+npm install react-app-rewired react-app-rewire-postcss --save-dev
+```
+
+Use **React App Rewire PostCSS** and **PostCSS Clamp** in your
+`config-overrides.js` file:
+
+```js
+const reactAppRewirePostcss = require('react-app-rewire-postcss');
+const postcssClamp = require('postcss-clamp');
+
+module.exports = config => reactAppRewirePostcss(config, {
+ plugins: () => [
+ postcssClamp(/* pluginOptions */)
+ ]
+});
+```
+
+## Gulp
+
+Add [Gulp PostCSS] to your project:
+
+```bash
+npm install gulp-postcss --save-dev
+```
+
+Use **PostCSS Clamp** in your Gulpfile:
+
+```js
+const postcss = require('gulp-postcss');
+const postcssClamp = require('postcss-clamp');
+
+gulp.task('css', () => gulp.src('./src/*.css').pipe(
+ postcss([
+ postcssClamp(/* pluginOptions */)
+ ])
+).pipe(
+ gulp.dest('.')
+));
+```
+
+## Grunt
+
+Add [Grunt PostCSS] to your project:
+
+```bash
+npm install grunt-postcss --save-dev
+```
+
+Use **PostCSS Clamp** in your Gruntfile:
+
+```js
+const postcssClamp = require('postcss-clamp');
+
+grunt.loadNpmTasks('grunt-postcss');
+
+grunt.initConfig({
+ postcss: {
+ options: {
+ use: [
+ postcssClamp(/* pluginOptions */)
+ ]
+ },
+ dist: {
+ src: '*.css'
+ }
+ }
+});
+```
+
+[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
+[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
+[PostCSS]: https://github.com/postcss/postcss
+[PostCSS CLI]: https://github.com/postcss/postcss-cli
+[PostCSS Loader]: https://github.com/postcss/postcss-loader
+[PostCSS Clamp]: https://github.com/polemius/postcss-clamp
+[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss
+[React App Rewired]: https://github.com/timarney/react-app-rewired
diff --git a/node_modules/postcss-clamp/LICENSE b/node_modules/postcss-clamp/LICENSE
new file mode 100644
index 00000000..ca8f8e58
--- /dev/null
+++ b/node_modules/postcss-clamp/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright 2020 Ivan Menshykov <ivan.menshykov@gmail.com>
+
+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/node_modules/postcss-clamp/README.md b/node_modules/postcss-clamp/README.md
new file mode 100644
index 00000000..d6e56b39
--- /dev/null
+++ b/node_modules/postcss-clamp/README.md
@@ -0,0 +1,118 @@
+# PostCSS Clamp
+[![Build Status][ci-img]][ci] [![codecov.io][cov-img]][cov]
+
+[PostCSS] plugin to transform `clamp()` to combination of `min/max`.
+
+[PostCSS]: https://github.com/postcss/postcss
+[ci-img]: https://travis-ci.com/polemius/postcss-clamp.svg?branch=master
+[ci]: https://travis-ci.com/polemius/postcss-clamp
+[cov-img]: https://codecov.io/github/polemius/postcss-clamp/coverage.svg?branch=master
+[cov]: https://codecov.io/github/polemius/postcss-clamp?branch=master
+
+This plugin transform this css:
+
+```css
+.foo {
+ width: clamp(10px, 4em, 80px);
+}
+```
+
+into this:
+
+```css
+.foo {
+ width: max(10px, min(4em, 80px));
+}
+```
+
+Or with enabled options `precalculate`:
+
+```css
+.foo {
+ width: clamp(10em, 4px, 10px);
+}
+
+/* becomes */
+
+.foo {
+ width: max(10em, 14px);
+}
+```
+
+[!['Can I use' table](https://caniuse.bitsofco.de/image/css-math-functions.png)](https://caniuse.com/#feat=css-math-functions)
+
+## Instalation
+
+```bash
+$ npm install postcss postcss-clamp --save-dev
+or
+$ yarn add --dev postcss postcss-clamp
+```
+
+## Usage
+
+Use [PostCSS Clamp] as a [PostCSS] plugin:
+
+```js
+const postcss = require('postcss');
+const postcssClamp = require('postcss-clamp');
+
+postcss([
+ postcssClamp(/* pluginOptions */)
+]).process(YOUR_CSS /*, processOptions */);
+```
+
+[PostCSS Clamp] runs in all Node environments, with special instructions for:
+
+| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) |
+| --- | --- | --- | --- | --- | --- |
+
+See [PostCSS] docs for examples for your environment.
+
+## Options
+
+### precalculate
+
+The `precalculate` option determines whether values with the same unit
+should be precalculated. By default, these are not precalculation.
+
+```js
+postcssColorHexAlpha({
+ precalculate: true
+});
+```
+
+The second and third value has the same unit (`px`):
+
+```css
+.foo {
+ width: clamp(10em, 4px, 10px);
+}
+
+/* becomes */
+
+.foo {
+ width: max(10em, 14px);
+}
+```
+
+Here all values have the same unit:
+
+```css
+.foo {
+ width: clamp(10px, 4px, 10px);
+}
+
+/* becomes */
+
+.foo {
+ width: 24px;
+}
+```
+
+## LICENSE
+
+See [LICENSE](LICENSE)
+
+[PostCSS]: https://github.com/postcss/postcss
+[PostCSS Clamp]: https://github.com/polemius/postcss-clamp
diff --git a/node_modules/postcss-clamp/index.js b/node_modules/postcss-clamp/index.js
new file mode 100644
index 00000000..474e8a62
--- /dev/null
+++ b/node_modules/postcss-clamp/index.js
@@ -0,0 +1,126 @@
+let valueParser = require('postcss-value-parser')
+
+function parseValue (value) {
+ let parsed = value.match(/([\d.-]+)(.*)/)
+ if (!parsed || !parsed[1] || !parsed[2] || isNaN(parsed[1])) {
+ return undefined
+ }
+ return [parseFloat(parsed[1]), parsed[2]]
+}
+
+function compose (first, second, third) {
+ if (first && second && third) {
+ return `max(${first}, min(${second}, ${third}))`
+ }
+ if (first && second) {
+ return `max(${first}, ${second})`
+ }
+
+ return first
+}
+
+function updateValue (declaration, value, preserve) {
+ let newValue = value
+ let newValueAst = valueParser(value)
+ let valueAST = valueParser(declaration.value)
+ // Walk can't be interrupted, so we only care about first
+ let foundClamp = false
+
+ valueAST.walk((node, index, nodes) => {
+ let isClamp = node.type === 'function' && node.value === 'clamp'
+
+ if (!isClamp || foundClamp) {
+ return
+ }
+
+ foundClamp = true
+ nodes[index] = newValueAst
+ })
+
+ if (foundClamp) {
+ newValue = valueAST.toString()
+ }
+
+ if (preserve) {
+ declaration.cloneBefore({ value: newValue })
+ } else {
+ declaration.value = newValue
+ }
+}
+
+module.exports = opts => {
+ opts = opts || {}
+ let precalculate = opts.precalculate ? Boolean(opts.precalculate) : false
+ let preserve = opts.preserve ? Boolean(opts.preserve) : false
+
+ return {
+ postcssPlugin: 'postcss-clamp',
+ Declaration (decl) {
+ if (!decl || !decl.value.includes('clamp')) {
+ return
+ }
+ valueParser(decl.value).walk(node => {
+ let nodes = node.nodes
+ if (
+ node.type !== 'function' ||
+ node.value !== 'clamp' ||
+ nodes.length !== 5
+ ) {
+ return
+ }
+ let first = nodes[0]
+ let second = nodes[2]
+ let third = nodes[4]
+ let naive = compose(
+ valueParser.stringify(first),
+ valueParser.stringify(second),
+ valueParser.stringify(third)
+ )
+ if (!precalculate || second.type !== 'word' || third.type !== 'word') {
+ updateValue(decl, naive, preserve)
+ return
+ }
+ let parsedSecond = parseValue(second.value)
+ let parsedThird = parseValue(third.value)
+ if (parsedSecond === undefined || parsedThird === undefined) {
+ updateValue(decl, naive, preserve)
+ return
+ }
+ let [secondValue, secondUnit] = parsedSecond
+ let [thirdValue, thirdUnit] = parsedThird
+ if (secondUnit !== thirdUnit) {
+ updateValue(decl, naive, preserve)
+ return
+ }
+ let parsedFirst = parseValue(first.value)
+ if (parsedFirst === undefined) {
+ let secondThirdValue = `${secondValue + thirdValue}${secondUnit}`
+ updateValue(
+ decl,
+ compose(valueParser.stringify(first), secondThirdValue),
+ preserve
+ )
+ return
+ }
+ let [firstValue, firstUnit] = parsedFirst
+ if (firstUnit !== secondUnit) {
+ let secondThirdValue = `${secondValue + thirdValue}${secondUnit}`
+ updateValue(
+ decl,
+ compose(valueParser.stringify(first), secondThirdValue),
+ preserve
+ )
+ return
+ }
+
+ updateValue(
+ decl,
+ compose(`${firstValue + secondValue + thirdValue}${secondUnit}`),
+ preserve
+ )
+ })
+ }
+ }
+}
+
+module.exports.postcss = true
diff --git a/node_modules/postcss-clamp/index.test.js b/node_modules/postcss-clamp/index.test.js
new file mode 100644
index 00000000..91e21ec5
--- /dev/null
+++ b/node_modules/postcss-clamp/index.test.js
@@ -0,0 +1,221 @@
+let postcss = require('postcss')
+
+let clamp = require('./')
+
+async function run (input, output, opts) {
+ let result = await postcss([clamp(opts)]).process(input, {
+ from: '/test.css'
+ })
+ expect(result.css).toEqual(output)
+ expect(result.warnings()).toHaveLength(0)
+ return result
+}
+
+it('handle simple transformation (only values)', async () => {
+ await run(
+ 'a{ width: clamp(10px, 64px, 80px); }',
+ 'a{ width: max(10px, min(64px, 80px)); }'
+ )
+})
+
+it('handle simple transformation (only values) with preserve', async () => {
+ await run(
+ 'a{ width: clamp(10px, 64px, 80px); }',
+ 'a{ width: max(10px, min(64px, 80px)); width: clamp(10px, 64px, 80px); }',
+ { preserve: true }
+ )
+})
+
+it('handle transformation with functions', async () => {
+ await run(
+ 'a{ width: clamp(calc(100% - 10px), min(10px, 100%), max(40px, 4em)); }',
+ 'a{ width: max(calc(100% - 10px), min(min(10px, 100%), max(40px, 4em))); }'
+ )
+})
+
+it('handle transformation with functions with preserve', async () => {
+ await run(
+ 'a{ width: clamp(calc(100% - 10px), min(10px, 100%), max(40px, 4em)); }',
+ 'a{ width: max(calc(100% - 10px), min(min(10px, 100%), max(40px, 4em))); ' +
+ 'width: clamp(calc(100% - 10px), min(10px, 100%), max(40px, 4em)); }',
+ { preserve: true }
+ )
+})
+
+it('handle transformation with different units', async () => {
+ await run(
+ 'a{ width: clamp(10%, 2px, 4rem); }',
+ 'a{ width: max(10%, min(2px, 4rem)); }'
+ )
+})
+
+it('handle transformation with different units and preserve', async () => {
+ await run(
+ 'a{ width: clamp(10%, 2px, 4rem); }',
+ 'a{ width: max(10%, min(2px, 4rem)); width: clamp(10%, 2px, 4rem); }',
+ { preserve: true }
+ )
+})
+
+it('transform only function with 3 parameters', async () => {
+ await run(
+ 'a{ width: clamp(10%, 2px, 4rem);' +
+ '\nheight: clamp(10px, 20px, 30px, 40px); }',
+ 'a{ width: max(10%, min(2px, 4rem));' +
+ '\nheight: clamp(10px, 20px, 30px, 40px); }'
+ )
+})
+
+it('transform only clamp function', async () => {
+ await run(
+ 'a{ width: clamp(10%, 2px, 4rem);\nheight: calc(10px + 100%); }',
+ 'a{ width: max(10%, min(2px, 4rem));\nheight: calc(10px + 100%); }'
+ )
+})
+
+it('precalculate second and third with the same unit (int values)', async () => {
+ await run('a{ width: clamp(10%, 2px, 5px); }', 'a{ width: max(10%, 7px); }', {
+ precalculate: true
+ })
+})
+
+it('precalculate second and third with the same unit (float values)', async () => {
+ await run(
+ 'a{ width: clamp(10%, 2.5px, 5.1px); }',
+ 'a{ width: max(10%, 7.6px); }',
+ { precalculate: true }
+ )
+})
+
+it('precalculate second and third with the same unit (float and int values)', async () => {
+ await run(
+ 'a{ width: clamp(10%, 2.5px, 5px); }',
+ 'a{ width: max(10%, 7.5px); }',
+ { precalculate: true }
+ )
+})
+
+it('precalculate 2nd & 3rd with the same unit (float and int vals) & preserve', async () => {
+ await run(
+ 'a{ width: clamp(10%, 2.5px, 5px); }',
+ 'a{ width: max(10%, 7.5px); width: clamp(10%, 2.5px, 5px); }',
+ { precalculate: true, preserve: true }
+ )
+})
+
+it('precalculate all values with the same unit (int values)', async () => {
+ await run('a{ width: clamp(10px, 2px, 5px); }', 'a{ width: 17px; }', {
+ precalculate: true
+ })
+})
+
+it('precalculate all values with the same unit (float values)', async () => {
+ await run(
+ 'a{ width: clamp(10.4px, 2.11px, 5.9px); }',
+ 'a{ width: 18.41px; }',
+ { precalculate: true }
+ )
+})
+
+it('precalculate all values with the same unit (int and float values)', async () => {
+ await run('a{ width: clamp(10.4px, 2px, 5.9px); }', 'a{ width: 18.3px; }', {
+ precalculate: true
+ })
+})
+
+it('handle function with enable precalculation as third', async () => {
+ await run(
+ 'a{ width: clamp(10px, 2px, calc(10px + 100%)); }',
+ 'a{ width: max(10px, min(2px, calc(10px + 100%))); }',
+ { precalculate: true }
+ )
+})
+
+it('handle function with enable precalculation as second', async () => {
+ await run(
+ 'a{ width: clamp(10px, calc(10px + 100%), 2px); }',
+ 'a{ width: max(10px, min(calc(10px + 100%), 2px)); }',
+ { precalculate: true }
+ )
+})
+
+it('handle function with enable precalculation as first', async () => {
+ await run(
+ 'a{ width: clamp(calc(10px + 100%), 10px, 2px); }',
+ 'a{ width: max(calc(10px + 100%), 12px); }',
+ { precalculate: true }
+ )
+})
+
+it('handle function with enable precalculation as all', async () => {
+ await run(
+ 'a{ width: clamp(calc(10px + 100%), calc(10rem + 200%), 10px); }',
+ 'a{ width: max(calc(10px + 100%), min(calc(10rem + 200%), 10px)); }',
+ { precalculate: true }
+ )
+})
+
+it('handle not valid values', async () => {
+ await run('a{ width: clamp(a, b, c); }', 'a{ width: max(a, min(b, c)); }', {
+ precalculate: true
+ })
+})
+
+it('handle not valid values with preserve', async () => {
+ await run(
+ 'a{ width: clamp(a, b, c); }',
+ 'a{ width: max(a, min(b, c)); width: clamp(a, b, c); }',
+ { precalculate: true, preserve: true }
+ )
+})
+
+it('handle not valid values mixed with valid', async () => {
+ await run(
+ 'a{ width: clamp(a, 1px, 2em); }',
+ 'a{ width: max(a, min(1px, 2em)); }',
+ { precalculate: true }
+ )
+})
+
+it('handle not valid values mixed with valid and preserve', async () => {
+ await run(
+ 'a{ width: clamp(a, 1px, 2em); }',
+ 'a{ width: max(a, min(1px, 2em)); width: clamp(a, 1px, 2em); }',
+ { precalculate: true, preserve: true }
+ )
+})
+
+it('handle complex values', async () => {
+ await run(
+ 'a{ grid-template-columns: clamp(22rem, 40%, 32rem) minmax(0, 1fr); }',
+ 'a{ grid-template-columns: max(22rem, min(40%, 32rem)) minmax(0, 1fr); }'
+ )
+})
+
+it('handle multiple complex values', async () => {
+ await run(
+ 'a{ margin: clamp(1rem, 2%, 3rem) 4px clamp(5rem, 6%, 7rem) 8rem; }',
+ 'a{ margin: max(1rem, min(2%, 3rem)) 4px max(5rem, min(6%, 7rem)) 8rem; }'
+ )
+})
+
+it('handle calc', async () => {
+ await run(
+ 'a{ margin: 0 40px 0 calc(-1 * clamp(32px, 16vw, 64px)); }',
+ 'a{ margin: 0 40px 0 calc(-1 * max(32px, min(16vw, 64px))); }'
+ )
+})
+
+it('handle multiple calc', async () => {
+ await run(
+ 'a{ margin: calc(-1 * clamp(1px, 2vw, 3px)) calc(-1 * clamp(4px, 5vw, 6px)); }',
+ 'a{ margin: calc(-1 * max(1px, min(2vw, 3px))) calc(-1 * max(4px, min(5vw, 6px))); }'
+ )
+})
+
+it('handle nested clamp', async () => {
+ await run(
+ 'a{ font-size: clamp(clamp(1rem, 2vw, 3rem), 4vw, 5rem); }',
+ 'a{ font-size: max(max(1rem, min(2vw, 3rem)), min(4vw, 5rem)); }'
+ )
+})
diff --git a/node_modules/postcss-clamp/package.json b/node_modules/postcss-clamp/package.json
new file mode 100644
index 00000000..c4592cbd
--- /dev/null
+++ b/node_modules/postcss-clamp/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "postcss-clamp",
+ "version": "4.1.0",
+ "description": "PostCSS plugin to transform clamp() to combination of min/max",
+ "keywords": [
+ "postcss",
+ "css",
+ "postcss-plugin",
+ "clamp",
+ "min",
+ "max"
+ ],
+ "main": "index.js",
+ "repository": "polemius/postcss-clamp",
+ "author": "Ivan Menshykov <ivan.menshykov@gmail.com>",
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.6"
+ },
+ "engines": {
+ "node": ">=7.6.0"
+ }
+}