New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@react-pdf/stylesheet

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@react-pdf/stylesheet - npm Package Compare versions

Comparing version 5.2.2 to 6.0.0

lib/index.d.ts

1329

lib/index.js
import { compose, castArray, matchPercent } from '@react-pdf/fns';
import matchMedia from 'media-engine';
import hlsToHex from 'hsl-to-hex';
import colorString from 'color-string';
import parse$1 from 'postcss-value-parser/lib/parse.js';
import parseUnit from 'postcss-value-parser/lib/unit.js';
import hlsToHex from 'hsl-to-hex';
import colorString from 'color-string';
import matchMedia from 'media-engine';
/**
* Remove nil values from array
*
* @param array - Style array
* @returns Style array without nils
*/
const compact = (array) => array.filter(Boolean);
/**
* Merges style objects array
*
* @param styles - Style array
* @returns Merged style object
*/
const mergeStyles = (styles) => styles.reduce((acc, style) => {
const s = Array.isArray(style) ? flatten(style) : style;
Object.keys(s).forEach((key) => {
if (s[key] !== null && s[key] !== undefined) {
acc[key] = s[key];
}
});
return acc;
}, {});
/**
* Flattens an array of style objects, into one aggregated style object.
*
* @param styles - Style or style array
* @returns Flattened style object
*/
const flatten = compose(mergeStyles, compact, (castArray));
/**
* Resolves media queries in styles object
*
* @param container - Container for which styles are resolved
* @param style - Style description
* @returns Resolved style object
*/
const resolveMediaQueries = (container, style) => {
return Object.keys(style).reduce((acc, key) => {
if (/@media/.test(key)) {
return {
...acc,
...matchMedia({ [key]: style[key] }, container),
};
}
return { ...acc, [key]: style[key] };
}, {});
};
const isRgb = (value) => /rgba?/g.test(value);
const isHsl = (value) => /hsla?/g.test(value);
/**
* Transform rgb color to hexa
*
* @param value - Styles value
* @returns Transformed value
*/
const parseRgb = (value) => {
const rgb = colorString.get.rgb(value);
return colorString.to.hex(rgb);
};
/**
* Transform Hsl color to hexa
*
* @param value - Styles value
* @returns Transformed value
*/
const parseHsl = (value) => {
const hsl = colorString.get.hsl(value).map(Math.round);
const hex = hlsToHex(...hsl);
return hex.toUpperCase();
};
/**
* Transform given color to hexa
*
* @param value - Styles value
* @returns Transformed value
*/
const transformColor = (value) => {
if (isRgb(value))
return parseRgb(value);
if (isHsl(value))
return parseHsl(value);
return value;
};
/**
* Parses scalar value in value and unit pairs
*
* @param value - Scalar value
* @returns Parsed value
*/
const parseValue = (value) => {
if (typeof value === 'number')
return { value, unit: undefined };
const match = /^(-?\d*\.?\d+)(in|mm|cm|pt|vh|vw|px|rem)?$/g.exec(value);
return match
? { value: parseFloat(match[1]), unit: match[2] || 'pt' }
: { value, unit: undefined };
};
/**
* Transform given scalar value
*
* @param container
* @param value - Styles value
* @returns Transformed value
*/
const transformUnit = (container, value) => {
const scalar = parseValue(value);
const outputDpi = 72;
const inputDpi = container.dpi || 72;
const mmFactor = (1 / 25.4) * outputDpi;
const cmFactor = (1 / 2.54) * outputDpi;
if (typeof scalar.value !== 'number')
return scalar.value;
switch (scalar.unit) {
case 'rem':
return scalar.value * (container.remBase || 18);
case 'in':
return scalar.value * outputDpi;
case 'mm':
return scalar.value * mmFactor;
case 'cm':
return scalar.value * cmFactor;
case 'vh':
return scalar.value * (container.height / 100);
case 'vw':
return scalar.value * (container.width / 100);
case 'px':
return Math.round(scalar.value * (outputDpi / inputDpi));
default:
return scalar.value;
}
};
const processNumberValue = (key, value) => ({
[key]: parseFloat(value),
});
const processUnitValue = (key, value, container) => ({
[key]: transformUnit(container, value),
});
const processColorValue = (key, value) => {
const result = { [key]: transformColor(value) };
return result;
};
const processNoopValue = (key, value) => ({
[key]: value,
});
const BORDER_SHORTHAND_REGEX = /(-?\d+(\.\d+)?(in|mm|cm|pt|vw|vh|px|rem)?)\s(\S+)\s(.+)/;
const matchBorderShorthand = (value) => value.match(BORDER_SHORTHAND_REGEX) || [];
const resolveBorderShorthand = (key, value, container) => {
const match = matchBorderShorthand(`${value}`);
if (match) {
const widthMatch = match[1] || value;
const styleMatch = match[4] || value;
const colorMatch = match[5] || value;
const style = styleMatch;
const color = colorMatch ? transformColor(colorMatch) : undefined;
const width = widthMatch ? transformUnit(container, widthMatch) : undefined;
if (key.match(/(Top|Right|Bottom|Left)$/)) {
return {
[`${key}Color`]: color,
[`${key}Style`]: style,
[`${key}Width`]: width,
};
}
if (key.match(/Color$/)) {
return {
borderTopColor: color,
borderRightColor: color,
borderBottomColor: color,
borderLeftColor: color,
};
}
if (key.match(/Style$/)) {
if (typeof style === 'number')
throw new Error(`Invalid border style: ${style}`);
return {
borderTopStyle: style,
borderRightStyle: style,
borderBottomStyle: style,
borderLeftStyle: style,
};
}
if (key.match(/Width$/)) {
if (typeof width !== 'number')
throw new Error(`Invalid border width: ${width}`);
return {
borderTopWidth: width,
borderRightWidth: width,
borderBottomWidth: width,
borderLeftWidth: width,
};
}
if (key.match(/Radius$/)) {
const radius = value ? transformUnit(container, value) : undefined;
if (typeof radius !== 'number')
throw new Error(`Invalid border radius: ${radius}`);
return {
borderTopLeftRadius: radius,
borderTopRightRadius: radius,
borderBottomRightRadius: radius,
borderBottomLeftRadius: radius,
};
}
if (typeof width !== 'number')
throw new Error(`Invalid border width: ${width}`);
if (typeof style === 'number')
throw new Error(`Invalid border style: ${style}`);
return {
borderTopColor: color,
borderTopStyle: style,
borderTopWidth: width,
borderRightColor: color,
borderRightStyle: style,
borderRightWidth: width,
borderBottomColor: color,
borderBottomStyle: style,
borderBottomWidth: width,
borderLeftColor: color,
borderLeftStyle: style,
borderLeftWidth: width,
};
}
return { [key]: value };
};
const handlers$b = {
border: resolveBorderShorthand,
borderBottom: resolveBorderShorthand,
borderBottomColor: processColorValue,
borderBottomLeftRadius: processUnitValue,
borderBottomRightRadius: processUnitValue,
borderBottomStyle: processNoopValue,
borderBottomWidth: processUnitValue,
borderColor: resolveBorderShorthand,
borderLeft: resolveBorderShorthand,
borderLeftColor: processColorValue,
borderLeftStyle: processNoopValue,
borderLeftWidth: processUnitValue,
borderRadius: resolveBorderShorthand,
borderRight: resolveBorderShorthand,
borderRightColor: processColorValue,
borderRightStyle: processNoopValue,
borderRightWidth: processUnitValue,
borderStyle: resolveBorderShorthand,
borderTop: resolveBorderShorthand,
borderTopColor: processColorValue,
borderTopLeftRadius: processUnitValue,
borderTopRightRadius: processUnitValue,
borderTopStyle: processNoopValue,
borderTopWidth: processUnitValue,
borderWidth: resolveBorderShorthand,
};
const handlers$a = {
backgroundColor: processColorValue,
color: processColorValue,
opacity: processNumberValue,
};
const handlers$9 = {
height: processUnitValue,
maxHeight: processUnitValue,
maxWidth: processUnitValue,
minHeight: processUnitValue,
minWidth: processUnitValue,
width: processUnitValue,
};
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex#values
// TODO: change flex defaults to [0, 1, 'auto'] as in spec in next major release
const flexDefaults = [1, 1, 0];
/**
* @type {(number | 'auto')[]}
*/
const flexAuto = [1, 1, 'auto'];
const expandFlex = (key, value) => {
/**
* @type {(number | 'auto')[]}
*/
let defaults = flexDefaults;
let matches = [];
if (value === 'auto') {
defaults = flexAuto;
} else {
matches = `${value}`.split(' ');
}
const flexGrow = matches[0] || defaults[0];
const flexShrink = matches[1] || defaults[1];
const flexBasis = matches[2] || defaults[2];
return {
flexGrow,
flexShrink,
flexBasis
};
const processFlexShorthand = (key, value, container) => {
let defaults = flexDefaults;
let matches = [];
if (value === 'auto') {
defaults = flexAuto;
}
else {
matches = `${value}`.split(' ');
}
const flexGrow = transformUnit(container, matches[0] || defaults[0]);
const flexShrink = transformUnit(container, matches[1] || defaults[1]);
const flexBasis = transformUnit(container, matches[2] || defaults[2]);
return { flexGrow, flexShrink, flexBasis };
};
const handlers$8 = {
alignContent: processNoopValue,
alignItems: processNoopValue,
alignSelf: processNoopValue,
flex: processFlexShorthand,
flexBasis: processUnitValue,
flexDirection: processNoopValue,
flexFlow: processNoopValue,
flexGrow: processUnitValue,
flexShrink: processUnitValue,
flexWrap: processNoopValue,
justifyContent: processNoopValue,
justifySelf: processNoopValue,
};
/* eslint-disable no-plusplus */
// This file is ran directly with Node - needs to have .js extension
// eslint-disable-next-line import/extensions
const processGapShorthand = (key, value, container) => {
const match = `${value}`.split(' ');
const rowGap = transformUnit(container, match?.[0] || value);
const columnGap = transformUnit(container, match?.[1] || value);
return { rowGap, columnGap };
};
const handlers$7 = {
gap: processGapShorthand,
columnGap: processUnitValue,
rowGap: processUnitValue,
};
const handlers$6 = {
aspectRatio: processNumberValue,
bottom: processUnitValue,
display: processNoopValue,
left: processUnitValue,
position: processNoopValue,
right: processUnitValue,
top: processUnitValue,
overflow: processNoopValue,
zIndex: processNumberValue,
};
const BOX_MODEL_UNITS = 'px,in,mm,cm,pt,%,vw,vh';
const logError = (style, value) => {
console.error(`
const name = style.toString();
// eslint-disable-next-line no-console
console.error(`
@react-pdf/stylesheet parsing error:
${style}: ${value},
${' '.repeat(style.length + 2)}^
Unsupported ${style} value format
${name}: ${value},
${' '.repeat(name.length + 2)}^
Unsupported ${name} value format
`);
};
/**

@@ -57,699 +352,399 @@ * @param {Object} options

*/
const expandBoxModel = function (_temp) {
let {
expandsTo,
maxValues = 1,
autoSupported = false
} = _temp === void 0 ? {} : _temp;
return (model, value) => {
const expandBoxModel = ({ expandsTo, maxValues = 1, autoSupported = false, } = {}) => (model, value, container) => {
const nodes = parse$1(`${value}`);
const parts = [];
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
// value contains `calc`, `url` or other css function
// `,`, `/` or strings that unsupported by margin and padding
if (node.type === 'function' || node.type === 'string' || node.type === 'div') {
logError(model, value);
return {};
}
if (node.type === 'word') {
if (node.value === 'auto' && autoSupported) {
parts.push(node.value);
} else {
const result = parseUnit(node.value);
// when unit isn't specified this condition is true
if (result && BOX_MODEL_UNITS.includes(result.unit)) {
parts.push(node.value);
} else {
const node = nodes[i];
// value contains `calc`, `url` or other css function
// `,`, `/` or strings that unsupported by margin and padding
if (node.type === 'function' ||
node.type === 'string' ||
node.type === 'div') {
logError(model, value);
return {};
}
}
}
if (node.type === 'word') {
if (node.value === 'auto' && autoSupported) {
parts.push(node.value);
}
else {
const result = parseUnit(node.value);
// when unit isn't specified this condition is true
if (result && BOX_MODEL_UNITS.includes(result.unit)) {
parts.push(node.value);
}
else {
logError(model, value);
return {};
}
}
}
}
// checks that we have enough parsed values
if (parts.length > maxValues) {
logError(model, value);
return {};
logError(model, value);
return {};
}
const first = parts[0];
const first = transformUnit(container, parts[0]);
if (expandsTo) {
const second = parts[1] || parts[0];
const third = parts[2] || parts[0];
const fourth = parts[3] || parts[1] || parts[0];
return expandsTo({
first,
second,
third,
fourth
});
const second = transformUnit(container, parts[1] || parts[0]);
const third = transformUnit(container, parts[2] || parts[0]);
const fourth = transformUnit(container, parts[3] || parts[1] || parts[0]);
return expandsTo({ first, second, third, fourth });
}
return {
[model]: first
[model]: first,
};
};
};
const processMargin = expandBoxModel({
expandsTo: _ref => {
let {
first,
second,
third,
fourth
} = _ref;
return {
marginTop: first,
marginRight: second,
marginBottom: third,
marginLeft: fourth
};
},
maxValues: 4,
autoSupported: true
expandsTo: ({ first, second, third, fourth }) => ({
marginTop: first,
marginRight: second,
marginBottom: third,
marginLeft: fourth,
}),
maxValues: 4,
autoSupported: true,
});
const processMarginVertical = expandBoxModel({
expandsTo: _ref2 => {
let {
first,
second
} = _ref2;
return {
marginTop: first,
marginBottom: second
};
},
maxValues: 2,
autoSupported: true
expandsTo: ({ first, second }) => ({
marginTop: first,
marginBottom: second,
}),
maxValues: 2,
autoSupported: true,
});
const processMarginHorizontal = expandBoxModel({
expandsTo: _ref3 => {
let {
first,
second
} = _ref3;
return {
marginRight: first,
marginLeft: second
};
},
maxValues: 2,
autoSupported: true
expandsTo: ({ first, second }) => ({
marginRight: first,
marginLeft: second,
}),
maxValues: 2,
autoSupported: true,
});
const processMarginSingle = expandBoxModel({
autoSupported: true
autoSupported: true,
});
const BORDER_SHORTHAND_REGEX = /(-?\d+(\.\d+)?(in|mm|cm|pt|vw|vh|px|rem)?)\s(\S+)\s(.+)/;
const matchBorderShorthand = value => value.match(BORDER_SHORTHAND_REGEX) || [];
const expandBorders = (key, value) => {
const match = matchBorderShorthand(`${value}`);
if (match) {
const color = match[5] || value;
const style = match[4] || value;
const width = match[1] || value;
if (key.match(/(Top|Right|Bottom|Left)$/)) {
return {
[`${key}Color`]: color,
[`${key}Style`]: style,
[`${key}Width`]: width
};
}
if (key.match(/Color$/)) {
return {
borderTopColor: color,
borderRightColor: color,
borderBottomColor: color,
borderLeftColor: color
};
}
if (key.match(/Style$/)) {
return {
borderTopStyle: style,
borderRightStyle: style,
borderBottomStyle: style,
borderLeftStyle: style
};
}
if (key.match(/Width$/)) {
return {
borderTopWidth: width,
borderRightWidth: width,
borderBottomWidth: width,
borderLeftWidth: width
};
}
if (key.match(/Radius$/)) {
return {
borderTopLeftRadius: value,
borderTopRightRadius: value,
borderBottomRightRadius: value,
borderBottomLeftRadius: value
};
}
return {
borderTopColor: color,
borderTopStyle: style,
borderTopWidth: width,
borderRightColor: color,
borderRightStyle: style,
borderRightWidth: width,
borderBottomColor: color,
borderBottomStyle: style,
borderBottomWidth: width,
borderLeftColor: color,
borderLeftStyle: style,
borderLeftWidth: width
};
}
return value;
const handlers$5 = {
margin: processMargin,
marginBottom: processMarginSingle,
marginHorizontal: processMarginHorizontal,
marginLeft: processMarginSingle,
marginRight: processMarginSingle,
marginTop: processMarginSingle,
marginVertical: processMarginVertical,
};
const processPadding = expandBoxModel({
expandsTo: _ref => {
let {
first,
second,
third,
fourth
} = _ref;
return {
paddingTop: first,
paddingRight: second,
paddingBottom: third,
paddingLeft: fourth
};
},
maxValues: 4
expandsTo: ({ first, second, third, fourth }) => ({
paddingTop: first,
paddingRight: second,
paddingBottom: third,
paddingLeft: fourth,
}),
maxValues: 4,
});
const processPaddingVertical = expandBoxModel({
expandsTo: _ref2 => {
let {
first,
second
} = _ref2;
return {
paddingTop: first,
paddingBottom: second
};
},
maxValues: 2
expandsTo: ({ first, second }) => ({
paddingTop: first,
paddingBottom: second,
}),
maxValues: 2,
});
const processPaddingHorizontal = expandBoxModel({
expandsTo: _ref3 => {
let {
first,
second
} = _ref3;
return {
paddingRight: first,
paddingLeft: second
};
},
maxValues: 2
expandsTo: ({ first, second }) => ({
paddingRight: first,
paddingLeft: second,
}),
maxValues: 2,
});
const processPaddingSingle = expandBoxModel();
const expandObjectPosition = (key, value) => {
const match = `${value}`.split(' ');
return {
objectPositionX: (match === null || match === void 0 ? void 0 : match[0]) || value,
objectPositionY: (match === null || match === void 0 ? void 0 : match[1]) || value
};
const handlers$4 = {
padding: processPadding,
paddingBottom: processPaddingSingle,
paddingHorizontal: processPaddingHorizontal,
paddingLeft: processPaddingSingle,
paddingRight: processPaddingSingle,
paddingTop: processPaddingSingle,
paddingVertical: processPaddingVertical,
};
const Y_AXIS_SHORTHANDS = {
top: true,
bottom: true
const offsetKeyword = (value) => {
switch (value) {
case 'top':
case 'left':
return '0%';
case 'right':
case 'bottom':
return '100%';
case 'center':
return '50%';
default:
return value;
}
};
const sortTransformOriginPair = (a, b) => {
if (Y_AXIS_SHORTHANDS[a]) return 1;
if (Y_AXIS_SHORTHANDS[b]) return -1;
return 0;
};
const getTransformOriginPair = values => {
if (!values || values.length === 0) return ['center', 'center'];
const pair = values.length === 1 ? [values[0], 'center'] : values;
return pair.sort(sortTransformOriginPair);
};
// Transforms shorthand transformOrigin values
const expandTransformOrigin = (key, value) => {
const match = `${value}`.split(' ');
const pair = getTransformOriginPair(match);
return {
transformOriginX: pair[0],
transformOriginY: pair[1]
};
const processObjectPosition = (key, value, container) => {
const match = `${value}`.split(' ');
const objectPositionX = offsetKeyword(transformUnit(container, match?.[0] || value));
const objectPositionY = offsetKeyword(transformUnit(container, match?.[1] || value));
return { objectPositionX, objectPositionY };
};
const expandGap = (key, value) => {
const match = `${value}`.split(' ');
return {
rowGap: (match === null || match === void 0 ? void 0 : match[0]) || value,
columnGap: (match === null || match === void 0 ? void 0 : match[1]) || value
};
const processObjectPositionValue = (key, value, container) => ({
[key]: offsetKeyword(transformUnit(container, value)),
});
const handlers$3 = {
objectPosition: processObjectPosition,
objectPositionX: processObjectPositionValue,
objectPositionY: processObjectPositionValue,
objectFit: processNoopValue,
};
const shorthands = {
flex: expandFlex,
gap: expandGap,
margin: processMargin,
marginHorizontal: processMarginHorizontal,
marginVertical: processMarginVertical,
marginTop: processMarginSingle,
marginRight: processMarginSingle,
marginBottom: processMarginSingle,
marginLeft: processMarginSingle,
padding: processPadding,
paddingHorizontal: processPaddingHorizontal,
paddingVertical: processPaddingVertical,
paddingTop: processPaddingSingle,
paddingRight: processPaddingSingle,
paddingBottom: processPaddingSingle,
paddingLeft: processPaddingSingle,
border: expandBorders,
borderTop: expandBorders,
borderRight: expandBorders,
borderBottom: expandBorders,
borderLeft: expandBorders,
borderColor: expandBorders,
borderRadius: expandBorders,
borderStyle: expandBorders,
borderWidth: expandBorders,
objectPosition: expandObjectPosition,
transformOrigin: expandTransformOrigin
const castInt = (value) => {
if (typeof value === 'number')
return value;
return parseInt(value, 10);
};
/**
* Transforms style key-value
*
* @param {string} key style key
* @param {string} value style value
* @returns {string | Number} transformed style values
*/
const expandStyle = (key, value) => {
return shorthands[key] ? shorthands[key](key, value) : {
[key]: value
};
const FONT_WEIGHTS = {
thin: 100,
hairline: 100,
ultralight: 200,
extralight: 200,
light: 300,
normal: 400,
medium: 500,
semibold: 600,
demibold: 600,
bold: 700,
ultrabold: 800,
extrabold: 800,
heavy: 900,
black: 900,
};
/**
* Expand the shorthand properties.
*
* @param {Object} style object
* @returns {Object} expanded style object
*/
const expand = style => {
if (!style) return style;
const propsArray = Object.keys(style);
const resolvedStyle = {};
for (let i = 0; i < propsArray.length; i += 1) {
const key = propsArray[i];
const value = style[key];
const extended = expandStyle(key, value);
const keys = Object.keys(extended);
for (let j = 0; j < keys.length; j += 1) {
const propName = keys[j];
const propValue = extended[propName];
resolvedStyle[propName] = propValue;
}
}
return resolvedStyle;
const transformFontWeight = (value) => {
if (!value)
return FONT_WEIGHTS.normal;
if (typeof value === 'number')
return value;
const lv = value.toLowerCase();
if (FONT_WEIGHTS[lv])
return FONT_WEIGHTS[lv];
return castInt(value);
};
/**
* Remove nil values from array
*
* @template T
* @param {(T | null | undefined)[]} array
* @returns {T[]} array without nils
*/
const compact = array => array.filter(Boolean);
/**
* Merges style objects array
*
* @param {Object[]} styles style objects array
* @returns {Object} merged style object
*/
const mergeStyles = styles => styles.reduce((acc, style) => {
const s = Array.isArray(style) ? flatten(style) : style;
Object.keys(s).forEach(key => {
if (s[key] !== null && s[key] !== undefined) {
acc[key] = s[key];
}
});
return acc;
}, {});
/**
* Flattens an array of style objects, into one aggregated style object.
*
* @param {Object[]} styles style objects array
* @returns {Object} flattened style object
*/
const flatten = compose(mergeStyles, compact, castArray);
/**
* Parses scalar value in value and unit pairs
*
* @param {string} value scalar value
* @returns {Object} parsed value
*/
const parseValue = value => {
const match = /^(-?\d*\.?\d+)(in|mm|cm|pt|vh|vw|px|rem)?$/g.exec(value);
return match ? {
value: parseFloat(match[1]),
unit: match[2] || 'pt'
} : {
value,
unit: undefined
};
const processFontWeight = (key, value) => {
return { [key]: transformFontWeight(value) };
};
/**
* Transform given scalar value
*
* @param {Object} container
* @param {string} value styles value
* @returns {Object} transformed value
*/
const transformUnit = (container, value) => {
const scalar = parseValue(value);
const outputDpi = 72;
const inputDpi = container.dpi || 72;
const mmFactor = 1 / 25.4 * outputDpi;
const cmFactor = 1 / 2.54 * outputDpi;
switch (scalar.unit) {
case 'rem':
return scalar.value * (container.remBase || 18);
case 'in':
return scalar.value * outputDpi;
case 'mm':
return scalar.value * mmFactor;
case 'cm':
return scalar.value * cmFactor;
case 'vh':
return scalar.value * (container.height / 100);
case 'vw':
return scalar.value * (container.width / 100);
case 'px':
return Math.round(scalar.value * (outputDpi / inputDpi));
default:
return scalar.value;
}
const transformLineHeight = (value, styles, container) => {
if (value === '')
return value;
const fontSize = transformUnit(container, styles.fontSize || 18);
const lineHeight = transformUnit(container, value);
// Percent values: use this number multiplied by the element's font size
const { percent } = matchPercent(lineHeight) || {};
if (percent)
return percent * fontSize;
// Unitless values: use this number multiplied by the element's font size
return isNaN(value) ? lineHeight : lineHeight * fontSize;
};
const isRgb = value => /rgba?/g.test(value);
const isHsl = value => /hsla?/g.test(value);
/**
* Transform rgb color to hexa
*
* @param {string} value styles value
* @returns {Object} transformed value
*/
const parseRgb = value => {
const rgb = colorString.get.rgb(value);
return colorString.to.hex(rgb);
const processLineHeight = (key, value, container, styles) => {
return {
[key]: transformLineHeight(value, styles, container),
};
};
/**
* Transform Hsl color to hexa
*
* @param {string} value styles value
* @returns {Object} transformed value
*/
const parseHsl = value => {
const hsl = colorString.get.hsl(value).map(Math.round);
const hex = hlsToHex(...hsl);
return hex.toUpperCase();
const handlers$2 = {
fontFamily: processNoopValue,
fontSize: processUnitValue,
fontStyle: processNoopValue,
fontWeight: processFontWeight,
letterSpacing: processUnitValue,
lineHeight: processLineHeight,
maxLines: processNumberValue,
textAlign: processNoopValue,
textDecoration: processNoopValue,
textDecorationColor: processColorValue,
textDecorationStyle: processNoopValue,
textIndent: processNoopValue,
textOverflow: processNoopValue,
textTransform: processNoopValue,
verticalAlign: processNoopValue,
};
/**
* Transform given color to hexa
*
* @param {string} value styles value
* @returns {Object} transformed value
*/
const transformColor = value => {
if (isRgb(value)) return parseRgb(value);
if (isHsl(value)) return parseHsl(value);
return value;
const matchNumber = (value) => typeof value === 'string' && /^-?\d*\.?\d*$/.test(value);
const castFloat = (value) => {
if (typeof value !== 'string')
return value;
if (matchNumber(value))
return parseFloat(value);
return value;
};
const parse = transformString => {
const transforms = transformString.trim().split(/\)[ ,]|\)/);
// Handle "initial", "inherit", "unset".
if (transforms.length === 1) {
return [[transforms[0], true]];
}
const parsed = [];
for (let i = 0; i < transforms.length; i += 1) {
const transform = transforms[i];
if (transform) {
const [name, rawValue] = transform.split('(');
const splitChar = rawValue.indexOf(',') >= 0 ? ',' : ' ';
const value = rawValue.split(splitChar).map(val => val.trim());
parsed.push({
operation: name.trim(),
value
});
const parse = (transformString) => {
const transforms = transformString.trim().split(/\)[ ,]|\)/);
// Handle "initial", "inherit", "unset".
if (transforms.length === 1) {
return [[transforms[0], true]];
}
}
return parsed;
const parsed = [];
for (let i = 0; i < transforms.length; i += 1) {
const transform = transforms[i];
if (transform) {
const [name, rawValue] = transform.split('(');
const splitChar = rawValue.indexOf(',') >= 0 ? ',' : ' ';
const value = rawValue.split(splitChar).map((val) => val.trim());
parsed.push({ operation: name.trim(), value });
}
}
return parsed;
};
const parseAngle = value => {
const unitsRegexp = /(-?\d*\.?\d*)(\w*)?/i;
const [, angle, unit] = unitsRegexp.exec(value);
const number = Number.parseFloat(angle);
return unit === 'rad' ? number * 180 / Math.PI : number;
const parseAngle = (value) => {
const unitsRegexp = /(-?\d*\.?\d*)(\w*)?/i;
const [, angle, unit] = unitsRegexp.exec(value);
const number = Number.parseFloat(angle);
return unit === 'rad' ? (number * 180) / Math.PI : number;
};
const normalizeTransformOperation = _ref => {
let {
operation,
value
} = _ref;
switch (operation) {
case 'scale':
{
const [scaleX, scaleY = scaleX] = value.map(num => Number.parseFloat(num));
return {
operation: 'scale',
value: [scaleX, scaleY]
};
}
case 'scaleX':
{
return {
operation: 'scale',
value: [Number.parseFloat(value), 1]
};
}
case 'scaleY':
{
return {
operation: 'scale',
value: [1, Number.parseFloat(value)]
};
}
case 'rotate':
{
return {
operation: 'rotate',
value: [parseAngle(value)]
};
}
case 'translate':
{
return {
operation: 'translate',
value: value.map(num => Number.parseFloat(num))
};
}
case 'translateX':
{
return {
operation: 'translate',
value: [Number.parseFloat(value), 0]
};
}
case 'translateY':
{
return {
operation: 'translate',
value: [0, Number.parseFloat(value)]
};
}
case 'skew':
{
return {
operation: 'skew',
value: value.map(parseAngle)
};
}
case 'skewX':
{
return {
operation: 'skew',
value: [parseAngle(value), 0]
};
}
case 'skewY':
{
return {
operation: 'skew',
value: [0, parseAngle(value)]
};
}
default:
{
return {
operation,
value: value.map(num => Number.parseFloat(num))
};
}
}
const normalizeTransformOperation = ({ operation, value }) => {
switch (operation) {
case 'scale': {
const [scaleX, scaleY = scaleX] = value.map((num) => Number.parseFloat(num));
return { operation: 'scale', value: [scaleX, scaleY] };
}
case 'scaleX': {
return { operation: 'scale', value: [Number.parseFloat(value), 1] };
}
case 'scaleY': {
return { operation: 'scale', value: [1, Number.parseFloat(value)] };
}
case 'rotate': {
return { operation: 'rotate', value: [parseAngle(value)] };
}
case 'translate': {
return {
operation: 'translate',
value: value.map((num) => Number.parseFloat(num)),
};
}
case 'translateX': {
return {
operation: 'translate',
value: [Number.parseFloat(value), 0],
};
}
case 'translateY': {
return { operation: 'translate', value: [0, Number.parseFloat(value)] };
}
case 'skew': {
return { operation: 'skew', value: value.map(parseAngle) };
}
case 'skewX': {
return { operation: 'skew', value: [parseAngle(value), 0] };
}
case 'skewY': {
return { operation: 'skew', value: [0, parseAngle(value)] };
}
default: {
return { operation, value: value.map((num) => Number.parseFloat(num)) };
}
}
};
const normalize = operations => {
return operations.map(operation => normalizeTransformOperation(operation));
const normalize = (operations) => {
return operations.map((operation) => normalizeTransformOperation(operation));
};
const processTransform = value => {
if (typeof value !== 'string') return value;
return normalize(parse(value));
const processTransform = (key, value) => {
if (typeof value !== 'string')
return { [key]: value };
return { [key]: normalize(parse(value)) };
};
const FONT_WEIGHTS = {
thin: 100,
hairline: 100,
ultralight: 200,
extralight: 200,
light: 300,
normal: 400,
medium: 500,
semibold: 600,
demibold: 600,
bold: 700,
ultrabold: 800,
extrabold: 800,
heavy: 900,
black: 900
const Y_AXIS_SHORTHANDS = { top: true, bottom: true };
const sortTransformOriginPair = (a, b) => {
if (Y_AXIS_SHORTHANDS[a])
return 1;
if (Y_AXIS_SHORTHANDS[b])
return -1;
return 0;
};
const processFontWeight = value => {
if (!value) return FONT_WEIGHTS.normal;
if (typeof value === 'number') return value;
const lv = value.toLowerCase();
if (FONT_WEIGHTS[lv]) return FONT_WEIGHTS[lv];
return value;
const getTransformOriginPair = (values) => {
if (!values || values.length === 0)
return ['center', 'center'];
const pair = values.length === 1 ? [values[0], 'center'] : values;
return pair.sort(sortTransformOriginPair);
};
/* eslint-disable no-restricted-globals */
const processLineHeight = (value, styles) => {
if (value === '') return value;
const {
fontSize = 18
} = styles;
// Percent values: use this number multiplied by the element's font size
const {
percent
} = matchPercent(value) || {};
if (percent) return percent * fontSize;
// Unitless values: use this number multiplied by the element's font size
return isNaN(value) ? value : value * fontSize;
// Transforms shorthand transformOrigin values
const processTransformOriginShorthand = (key, value, container) => {
const match = `${value}`.split(' ');
const pair = getTransformOriginPair(match);
const transformOriginX = transformUnit(container, pair[0]);
const transformOriginY = transformUnit(container, pair[1]);
return {
transformOriginX: offsetKeyword(transformOriginX) || castFloat(transformOriginX),
transformOriginY: offsetKeyword(transformOriginY) || castFloat(transformOriginY),
};
};
const matchNumber = value => typeof value === 'string' && /^-?\d*\.?\d*$/.test(value);
const castFloat = value => {
if (typeof value !== 'string') return value;
if (matchNumber(value)) return parseFloat(value);
return value;
const processTransformOriginValue = (key, value, container) => {
const v = transformUnit(container, value);
return { [key]: offsetKeyword(v) || castFloat(v) };
};
const offsetKeyword = value => {
switch (value) {
case 'top':
case 'left':
return '0%';
case 'right':
case 'bottom':
return '100%';
case 'center':
return '50%';
default:
return null;
}
const handlers$1 = {
transform: processTransform,
transformOrigin: processTransformOriginShorthand,
transformOriginX: processTransformOriginValue,
transformOriginY: processTransformOriginValue,
};
const transformObjectPosition = value => offsetKeyword(value) || castFloat(value);
const transformTransformOrigin = value => offsetKeyword(value) || castFloat(value);
const handlers = {
transform: processTransform,
fontWeight: processFontWeight,
lineHeight: processLineHeight,
objectPositionX: transformObjectPosition,
objectPositionY: transformObjectPosition,
transformOriginX: transformTransformOrigin,
transformOriginY: transformTransformOrigin
fill: processColorValue,
stroke: processColorValue,
strokeDasharray: processNoopValue,
strokeWidth: processUnitValue,
fillOpacity: processNumberValue,
strokeOpacity: processNumberValue,
fillRule: processNoopValue,
textAnchor: processNoopValue,
strokeLinecap: processNoopValue,
strokeLinejoin: processNoopValue,
visibility: processNoopValue,
clipPath: processNoopValue,
dominantBaseline: processNoopValue,
};
const transformStyle = (key, value, styles, container) => {
const result = handlers[key] ? handlers[key](value, styles) : value;
return transformColor(transformUnit(container, castFloat(result)));
};
/**
* @typedef {Function} Transform
* @param {Object} style styles object
* @returns {Object} transformed styles
*/
/**
* Transform styles values
*
* @param {Object} container
* @returns {Transform} transform function
*/
const transform = container => styles => {
if (!styles) return styles;
const propsArray = Object.keys(styles);
const resolvedStyle = {};
for (let i = 0; i < propsArray.length; i += 1) {
const key = propsArray[i];
const value = styles[key];
const transformed = transformStyle(key, value, styles, container);
resolvedStyle[key] = transformed;
}
return resolvedStyle;
const shorthands = {
...handlers$b,
...handlers$a,
...handlers$9,
...handlers$8,
...handlers$7,
...handlers$6,
...handlers$5,
...handlers$4,
...handlers$3,
...handlers$2,
...handlers$1,
...handlers,
};
/**
* Resolves media queries in styles object
* Expand the shorthand properties.
*
* @param {Object} container
* @param {Object} styles object
* @param style - Style object
* @returns Expanded style object
*/
const resolveMediaQueries = (container, styles) => {
return Object.keys(styles).reduce((acc, key) => {
if (/@media/.test(key)) {
return {
...acc,
...matchMedia({
[key]: styles[key]
}, container)
};
const resolve = (container) => (style) => {
const propsArray = Object.keys(style);
const resolvedStyle = {};
for (let i = 0; i < propsArray.length; i += 1) {
const key = propsArray[i];
const value = style[key];
if (!shorthands[key]) {
resolvedStyle[key] = value;
continue;
}
const resolved = shorthands[key](key, value, container, style);
const keys = Object.keys(resolved);
for (let j = 0; j < keys.length; j += 1) {
const propName = keys[j];
const propValue = resolved[propName];
resolvedStyle[propName] = propValue;
}
}
return {
...acc,
[key]: styles[key]
};
}, {});
return resolvedStyle;
};

@@ -760,11 +755,11 @@

*
* @param {Object} container
* @param {Object} style object
* @returns {Object} resolved style object
* @param container
* @param style - Style
* @returns Resolved style
*/
const resolveStyles = (container, style) => {
const computeMediaQueries = value => resolveMediaQueries(container, value);
return compose(transform(container), expand, computeMediaQueries, flatten)(style);
const computeMediaQueries = (value) => resolveMediaQueries(container, value);
return compose(resolve(container), computeMediaQueries, flatten)(style);
};
export { resolveStyles as default, flatten, processTransform, transformColor };
export { resolveStyles as default, flatten, transformColor };
{
"name": "@react-pdf/stylesheet",
"version": "5.2.2",
"version": "6.0.0",
"license": "MIT",

@@ -10,2 +10,3 @@ "description": "A styles engine for Node and the browser",

"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"repository": {

@@ -22,5 +23,4 @@ "type": "git",

"dependencies": {
"@babel/runtime": "^7.20.13",
"@react-pdf/fns": "3.1.0",
"@react-pdf/types": "^2.7.1",
"@react-pdf/fns": "3.1.1",
"@react-pdf/types": "^2.8.0",
"color-string": "^1.9.1",

@@ -27,0 +27,0 @@ "hsl-to-hex": "^1.0.0",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc