ui
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
Copyright (c) Ben Briggs <beneb.info@gmail.com> (http://beneb.info)
|
||||
|
||||
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.
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
# [postcss][postcss]-convert-values
|
||||
|
||||
> Convert values with PostCSS (e.g. ms -> s)
|
||||
|
||||
## Install
|
||||
|
||||
With [npm](https://npmjs.org/package/postcss-convert-values) do:
|
||||
|
||||
```
|
||||
npm install postcss-convert-values --save
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
This plugin reduces CSS size by converting values to use different units
|
||||
where possible; for example, `500ms` can be represented as `.5s`. You can
|
||||
read more about these units in [this article][csstricks].
|
||||
|
||||
### Input
|
||||
|
||||
```css
|
||||
h1 {
|
||||
font-size: 16px;
|
||||
width: 0em
|
||||
}
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
```css
|
||||
h1 {
|
||||
font-size: 1pc;
|
||||
width: 0
|
||||
}
|
||||
```
|
||||
|
||||
Note that this plugin only covers conversions for duration and absolute length
|
||||
values. For color conversions, use [postcss-colormin][colormin].
|
||||
|
||||
## API
|
||||
|
||||
### convertValues([options])
|
||||
|
||||
#### options
|
||||
|
||||
##### length
|
||||
|
||||
Type: `boolean`
|
||||
Default: `true`
|
||||
|
||||
Pass `false` to disable conversion from `px` to other absolute length units,
|
||||
such as `pc` & `pt` & vice versa.
|
||||
|
||||
##### time
|
||||
|
||||
Type: `boolean`
|
||||
Default: `true`
|
||||
|
||||
Pass `false` to disable conversion from `ms` to `s` & vice versa.
|
||||
|
||||
##### angle
|
||||
|
||||
Type: `boolean`
|
||||
Default: `true`
|
||||
|
||||
Pass `false` to disable conversion from `deg` to `turn` & vice versa.
|
||||
|
||||
##### precision
|
||||
|
||||
Type: `boolean|number`
|
||||
Default: `false`
|
||||
|
||||
Specify any numeric value here to round `px` values to that many decimal places;
|
||||
for example, using `{precision: 2}` will round `6.66667px` to `6.67px`, and
|
||||
`{precision: 0}` will round it to `7px`. Passing `false` (the default) will
|
||||
leave these values as is.
|
||||
|
||||
It is recommended for most use cases to set this option to `2`.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
See the [PostCSS documentation](https://github.com/postcss/postcss#usage) for
|
||||
examples for your environment.
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
See [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Ben Briggs](http://beneb.info)
|
||||
|
||||
|
||||
[postcss]: https://github.com/postcss/postcss
|
||||
[csstricks]: https://css-tricks.com/the-lengths-of-css/
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "postcss-convert-values",
|
||||
"version": "5.1.0",
|
||||
"description": "Convert values with PostCSS (e.g. ms -> s)",
|
||||
"main": "src/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"LICENSE-MIT",
|
||||
"src",
|
||||
"types"
|
||||
],
|
||||
"keywords": [
|
||||
"css",
|
||||
"optimisation",
|
||||
"postcss",
|
||||
"postcss-plugin"
|
||||
],
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/cssnano/cssnano",
|
||||
"author": {
|
||||
"name": "Ben Briggs",
|
||||
"email": "beneb.info@gmail.com",
|
||||
"url": "http://beneb.info"
|
||||
},
|
||||
"repository": "cssnano/cssnano",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/cssnano/cssnano/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss": "^8.2.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.2.15"
|
||||
},
|
||||
"readme": "# [postcss][postcss]-convert-values\n\n> Convert values with PostCSS (e.g. ms -> s)\n\n## Install\n\nWith [npm](https://npmjs.org/package/postcss-convert-values) do:\n\n```\nnpm install postcss-convert-values --save\n```\n\n## Example\n\nThis plugin reduces CSS size by converting values to use different units\nwhere possible; for example, `500ms` can be represented as `.5s`. You can\nread more about these units in [this article][csstricks].\n\n### Input\n\n```css\nh1 {\n font-size: 16px;\n width: 0em\n}\n```\n\n### Output\n\n```css\nh1 {\n font-size: 1pc;\n width: 0\n}\n```\n\nNote that this plugin only covers conversions for duration and absolute length\nvalues. For color conversions, use [postcss-colormin][colormin].\n\n## API\n\n### convertValues([options])\n\n#### options\n\n##### length\n\nType: `boolean`\nDefault: `true`\n\nPass `false` to disable conversion from `px` to other absolute length units,\nsuch as `pc` & `pt` & vice versa.\n\n##### time\n\nType: `boolean`\nDefault: `true`\n\nPass `false` to disable conversion from `ms` to `s` & vice versa.\n\n##### angle\n\nType: `boolean`\nDefault: `true`\n\nPass `false` to disable conversion from `deg` to `turn` & vice versa.\n\n##### precision\n\nType: `boolean|number`\nDefault: `false`\n\nSpecify any numeric value here to round `px` values to that many decimal places;\nfor example, using `{precision: 2}` will round `6.66667px` to `6.67px`, and\n`{precision: 0}` will round it to `7px`. Passing `false` (the default) will\nleave these values as is.\n\nIt is recommended for most use cases to set this option to `2`.\n\n\n## Usage\n\nSee the [PostCSS documentation](https://github.com/postcss/postcss#usage) for\nexamples for your environment.\n\n\n## Contributors\n\nSee [CONTRIBUTORS.md](https://github.com/cssnano/cssnano/blob/master/CONTRIBUTORS.md).\n\n\n## License\n\nMIT © [Ben Briggs](http://beneb.info)\n\n\n[postcss]: https://github.com/postcss/postcss\n[csstricks]: https://css-tricks.com/the-lengths-of-css/\n"
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
'use strict';
|
||||
const valueParser = require('postcss-value-parser');
|
||||
const convert = require('./lib/convert.js');
|
||||
|
||||
const LENGTH_UNITS = new Set([
|
||||
'em',
|
||||
'ex',
|
||||
'ch',
|
||||
'rem',
|
||||
'vw',
|
||||
'vh',
|
||||
'vmin',
|
||||
'vmax',
|
||||
'cm',
|
||||
'mm',
|
||||
'q',
|
||||
'in',
|
||||
'pt',
|
||||
'pc',
|
||||
'px',
|
||||
]);
|
||||
|
||||
// These properties only accept percentages, so no point in trying to transform
|
||||
const notALength = new Set([
|
||||
'descent-override',
|
||||
'ascent-override',
|
||||
'font-stretch',
|
||||
'size-adjust',
|
||||
'line-gap-override',
|
||||
]);
|
||||
|
||||
// Can't change the unit on these properties when they're 0
|
||||
const keepWhenZero = new Set([
|
||||
'stroke-dashoffset',
|
||||
'stroke-width',
|
||||
'line-height',
|
||||
]);
|
||||
|
||||
/**
|
||||
* Numbers without digits after the dot are technically invalid,
|
||||
* but in that case css-value-parser returns the dot as part of the unit,
|
||||
* so we use this to remove the dot.
|
||||
*
|
||||
* @param {string} item
|
||||
* @return {string}
|
||||
*/
|
||||
function stripLeadingDot(item) {
|
||||
if (item.charCodeAt(0) === '.'.charCodeAt(0)) {
|
||||
return item.slice(1);
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {valueParser.Node} node
|
||||
* @param {Options} opts
|
||||
* @param {boolean} keepZeroUnit
|
||||
* @return {void}
|
||||
*/
|
||||
function parseWord(node, opts, keepZeroUnit) {
|
||||
const pair = valueParser.unit(node.value);
|
||||
if (pair) {
|
||||
const num = Number(pair.number);
|
||||
const u = stripLeadingDot(pair.unit);
|
||||
if (num === 0) {
|
||||
node.value =
|
||||
0 +
|
||||
(keepZeroUnit || (!LENGTH_UNITS.has(u.toLowerCase()) && u !== '%')
|
||||
? u
|
||||
: '');
|
||||
} else {
|
||||
node.value = convert(num, u, opts);
|
||||
|
||||
if (
|
||||
typeof opts.precision === 'number' &&
|
||||
u.toLowerCase() === 'px' &&
|
||||
pair.number.includes('.')
|
||||
) {
|
||||
const precision = Math.pow(10, opts.precision);
|
||||
node.value =
|
||||
Math.round(parseFloat(node.value) * precision) / precision + u;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {valueParser.WordNode} node
|
||||
* @return {void}
|
||||
*/
|
||||
function clampOpacity(node) {
|
||||
const pair = valueParser.unit(node.value);
|
||||
if (!pair) {
|
||||
return;
|
||||
}
|
||||
let num = Number(pair.number);
|
||||
if (num > 1) {
|
||||
node.value = pair.unit === '%' ? num + pair.unit : 1 + pair.unit;
|
||||
} else if (num < 0) {
|
||||
node.value = 0 + pair.unit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('postcss').Declaration} decl
|
||||
* @return {boolean}
|
||||
*/
|
||||
function shouldKeepZeroUnit(decl) {
|
||||
const { parent } = decl;
|
||||
const lowerCasedProp = decl.prop.toLowerCase();
|
||||
return (
|
||||
(decl.value.includes('%') &&
|
||||
(lowerCasedProp === 'max-height' || lowerCasedProp === 'height')) ||
|
||||
(parent &&
|
||||
parent.parent &&
|
||||
parent.parent.type === 'atrule' &&
|
||||
/** @type {import('postcss').AtRule} */ (
|
||||
parent.parent
|
||||
).name.toLowerCase() === 'keyframes' &&
|
||||
lowerCasedProp === 'stroke-dasharray') ||
|
||||
keepWhenZero.has(lowerCasedProp)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* @param {Options} opts
|
||||
* @param {import('postcss').Declaration} decl
|
||||
* @return {void}
|
||||
*/
|
||||
function transform(opts, decl) {
|
||||
const lowerCasedProp = decl.prop.toLowerCase();
|
||||
if (
|
||||
lowerCasedProp.includes('flex') ||
|
||||
lowerCasedProp.indexOf('--') === 0 ||
|
||||
notALength.has(lowerCasedProp)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
decl.value = valueParser(decl.value)
|
||||
.walk((node) => {
|
||||
const lowerCasedValue = node.value.toLowerCase();
|
||||
|
||||
if (node.type === 'word') {
|
||||
parseWord(node, opts, shouldKeepZeroUnit(decl));
|
||||
if (
|
||||
lowerCasedProp === 'opacity' ||
|
||||
lowerCasedProp === 'shape-image-threshold'
|
||||
) {
|
||||
clampOpacity(node);
|
||||
}
|
||||
} else if (node.type === 'function') {
|
||||
if (
|
||||
lowerCasedValue === 'calc' ||
|
||||
lowerCasedValue === 'min' ||
|
||||
lowerCasedValue === 'max' ||
|
||||
lowerCasedValue === 'clamp' ||
|
||||
lowerCasedValue === 'hsl' ||
|
||||
lowerCasedValue === 'hsla'
|
||||
) {
|
||||
valueParser.walk(node.nodes, (n) => {
|
||||
if (n.type === 'word') {
|
||||
parseWord(n, opts, true);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (lowerCasedValue === 'url') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
.toString();
|
||||
}
|
||||
|
||||
const plugin = 'postcss-convert-values';
|
||||
/**
|
||||
* @typedef {{precision: boolean | number, angle?: boolean, time?: boolean, length?: boolean}} Options */
|
||||
/**
|
||||
* @type {import('postcss').PluginCreator<Options>}
|
||||
* @param {Options} opts
|
||||
* @return {import('postcss').Plugin}
|
||||
*/
|
||||
function pluginCreator(opts = { precision: false }) {
|
||||
return {
|
||||
postcssPlugin: plugin,
|
||||
OnceExit(css) {
|
||||
css.walkDecls(transform.bind(null, opts));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pluginCreator.postcss = true;
|
||||
module.exports = pluginCreator;
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
'use strict';
|
||||
const lengthConv = new Map([
|
||||
['in', 96],
|
||||
['px', 1],
|
||||
['pt', 4 / 3],
|
||||
['pc', 16],
|
||||
]);
|
||||
|
||||
const timeConv = new Map([
|
||||
['s', 1000],
|
||||
['ms', 1],
|
||||
]);
|
||||
|
||||
const angleConv = new Map([
|
||||
['turn', 360],
|
||||
['deg', 1],
|
||||
]);
|
||||
/**
|
||||
* @param {number} number
|
||||
* @return {string}
|
||||
*/
|
||||
function dropLeadingZero(number) {
|
||||
const value = String(number);
|
||||
|
||||
if (number % 1) {
|
||||
if (value[0] === '0') {
|
||||
return value.slice(1);
|
||||
}
|
||||
|
||||
if (value[0] === '-' && value[1] === '0') {
|
||||
return '-' + value.slice(2);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* @param {number} number
|
||||
* @param {string} originalUnit
|
||||
* @param {Map<string, number>} conversions
|
||||
* @return {string}
|
||||
*/
|
||||
function transform(number, originalUnit, conversions) {
|
||||
let conversionUnits = [...conversions.keys()].filter((u) => {
|
||||
return originalUnit !== u;
|
||||
});
|
||||
|
||||
const base = number * /** @type {number} */ (conversions.get(originalUnit));
|
||||
|
||||
return conversionUnits
|
||||
.map(
|
||||
(u) =>
|
||||
dropLeadingZero(base / /** @type {number} */ (conversions.get(u))) + u
|
||||
)
|
||||
.reduce((a, b) => (a.length < b.length ? a : b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} number
|
||||
* @param {string} unit
|
||||
* @param {{time?: boolean, length?: boolean, angle?: boolean}} options
|
||||
* @return {string}
|
||||
*/
|
||||
module.exports = function (number, unit, { time, length, angle }) {
|
||||
let value = dropLeadingZero(number) + (unit ? unit : '');
|
||||
let converted;
|
||||
const lowerCaseUnit = unit.toLowerCase();
|
||||
if (length !== false && lengthConv.has(lowerCaseUnit)) {
|
||||
converted = transform(number, lowerCaseUnit, lengthConv);
|
||||
}
|
||||
|
||||
if (time !== false && timeConv.has(lowerCaseUnit)) {
|
||||
converted = transform(number, lowerCaseUnit, timeConv);
|
||||
}
|
||||
|
||||
if (angle !== false && angleConv.has(lowerCaseUnit)) {
|
||||
converted = transform(number, lowerCaseUnit, angleConv);
|
||||
}
|
||||
|
||||
if (converted && converted.length < value.length) {
|
||||
value = converted;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
export = pluginCreator;
|
||||
/**
|
||||
* @typedef {{precision: boolean | number, angle?: boolean, time?: boolean, length?: boolean}} Options */
|
||||
/**
|
||||
* @type {import('postcss').PluginCreator<Options>}
|
||||
* @param {Options} opts
|
||||
* @return {import('postcss').Plugin}
|
||||
*/
|
||||
declare function pluginCreator(opts?: Options): import('postcss').Plugin;
|
||||
declare namespace pluginCreator {
|
||||
export { postcss, Options };
|
||||
}
|
||||
type Options = {
|
||||
precision: boolean | number;
|
||||
angle?: boolean;
|
||||
time?: boolean;
|
||||
length?: boolean;
|
||||
};
|
||||
declare var postcss: true;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
declare function _exports(number: number, unit: string, { time, length, angle }: {
|
||||
time?: boolean;
|
||||
length?: boolean;
|
||||
angle?: boolean;
|
||||
}): string;
|
||||
export = _exports;
|
||||
Reference in New Issue
Block a user