77 lines
2.0 KiB
TypeScript
77 lines
2.0 KiB
TypeScript
/**
|
|
* respect https://github.com/cuth/postcss-pxtorem
|
|
*/
|
|
import unitless from '@emotion/unitless';
|
|
import type { CSSObject } from '..';
|
|
import type { Transformer } from './interface';
|
|
|
|
export interface Options {
|
|
/**
|
|
* The root font size.
|
|
* @default 16
|
|
*/
|
|
rootValue?: number;
|
|
/**
|
|
* The decimal numbers to allow the REM units to grow to.
|
|
* @default 5
|
|
*/
|
|
precision?: number;
|
|
/**
|
|
* Whether to allow px to be converted in media queries.
|
|
* @default false
|
|
*/
|
|
mediaQuery?: boolean;
|
|
}
|
|
|
|
const pxRegex = /url\([^)]+\)|var\([^)]+\)|(\d*\.?\d+)px/g;
|
|
|
|
function toFixed(number: number, precision: number) {
|
|
const multiplier = Math.pow(10, precision + 1),
|
|
wholeNumber = Math.floor(number * multiplier);
|
|
return (Math.round(wholeNumber / 10) * 10) / multiplier;
|
|
}
|
|
|
|
const transform = (options: Options = {}): Transformer => {
|
|
const { rootValue = 16, precision = 5, mediaQuery = false } = options;
|
|
|
|
const pxReplace = (m: string, $1: any) => {
|
|
if (!$1) return m;
|
|
const pixels = parseFloat($1);
|
|
// covenant: pixels <= 1, not transform to rem @zombieJ
|
|
if (pixels <= 1) return m;
|
|
const fixedVal = toFixed(pixels / rootValue, precision);
|
|
return `${fixedVal}rem`;
|
|
};
|
|
|
|
const visit = (cssObj: CSSObject): CSSObject => {
|
|
const clone: CSSObject = { ...cssObj };
|
|
|
|
Object.entries(cssObj).forEach(([key, value]) => {
|
|
if (typeof value === 'string' && value.includes('px')) {
|
|
const newValue = value.replace(pxRegex, pxReplace);
|
|
clone[key] = newValue;
|
|
}
|
|
|
|
// no unit
|
|
if (!unitless[key] && typeof value === 'number' && value !== 0) {
|
|
clone[key] = `${value}px`.replace(pxRegex, pxReplace);
|
|
}
|
|
|
|
// Media queries
|
|
const mergedKey = key.trim();
|
|
if (mergedKey.startsWith('@') && mergedKey.includes('px') && mediaQuery) {
|
|
const newKey = key.replace(pxRegex, pxReplace);
|
|
|
|
clone[newKey] = clone[key];
|
|
delete clone[key];
|
|
}
|
|
});
|
|
|
|
return clone;
|
|
};
|
|
|
|
return { visit };
|
|
};
|
|
|
|
export default transform;
|