Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@capsizecss/core

Package Overview
Dependencies
Maintainers
2
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@capsizecss/core - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

dist/declarations/src/createFontStack.d.ts

325

dist/capsizecss-core.browser.cjs.js

@@ -9,12 +9,11 @@ 'use strict';

}
if ('capHeight' in options && 'fontSize' in options) {
throw new Error('Please pass either `capHeight` OR `fontSize`, not both.');
}
var fontMetrics = options.fontMetrics;
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var specifiedFontSize;
var specifiedCapHeight;
const {
fontMetrics
} = options;
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
let specifiedFontSize;
let specifiedCapHeight;
if ('capHeight' in options) {

@@ -29,5 +28,3 @@ specifiedFontSize = options.capHeight / capHeightScale;

}
var specifiedLineHeight;
let specifiedLineHeight;
if ('lineGap' in options) {

@@ -38,7 +35,6 @@ specifiedLineHeight = specifiedCapHeight + options.lineGap;

}
return {
fontSize: specifiedFontSize,
lineHeight: specifiedLineHeight,
fontMetrics: fontMetrics
fontMetrics
};

@@ -54,32 +50,27 @@ }

*/
var round = function round(value) {
return parseFloat(value.toFixed(4));
};
const round = value => parseFloat(value.toFixed(4));
function precomputeValues(options) {
var _normaliseOptions = normaliseOptions(options),
fontSize = _normaliseOptions.fontSize,
lineHeight = _normaliseOptions.lineHeight,
fontMetrics = _normaliseOptions.fontMetrics;
var absoluteDescent = Math.abs(fontMetrics.descent);
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var descentScale = absoluteDescent / fontMetrics.unitsPerEm;
var ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
var lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
var contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
var lineHeightScale = contentArea / fontMetrics.unitsPerEm;
var lineHeightNormal = lineHeightScale * fontSize;
var allowForLineHeight = function allowForLineHeight(trim) {
const {
fontSize,
lineHeight,
fontMetrics
} = normaliseOptions(options);
const absoluteDescent = Math.abs(fontMetrics.descent);
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
const descentScale = absoluteDescent / fontMetrics.unitsPerEm;
const ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
const lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
const contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
const lineHeightScale = contentArea / fontMetrics.unitsPerEm;
const lineHeightNormal = lineHeightScale * fontSize;
const allowForLineHeight = trim => {
if (lineHeight) {
var specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
const specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
return trim - specifiedLineHeightOffset / fontSize;
}
return trim;
};
var capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
var baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
const capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
const baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
return {

@@ -93,10 +84,12 @@ fontSize: "".concat(round(fontSize), "px"),

var _createStyleObject = function _createStyleObject(_ref) {
var lineHeight = _ref.lineHeight,
fontSize = _ref.fontSize,
capHeightTrim = _ref.capHeightTrim,
baselineTrim = _ref.baselineTrim;
const _createStyleObject = _ref => {
let {
lineHeight,
fontSize,
capHeightTrim,
baselineTrim
} = _ref;
return {
fontSize: fontSize,
lineHeight: lineHeight,
fontSize,
lineHeight,
'::before': {

@@ -114,3 +107,2 @@ content: "''",

};
function createStyleObject(args) {

@@ -120,3 +112,2 @@ if ('capHeightTrim' in args) {

}
return _createStyleObject(precomputeValues(args));

@@ -130,3 +121,2 @@ }

var key, i;
for (i = 0; i < sourceKeys.length; i++) {

@@ -137,3 +127,2 @@ key = sourceKeys[i];

}
return target;

@@ -146,6 +135,4 @@ }

var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {

@@ -158,28 +145,240 @@ key = sourceSymbolKeys[i];

}
return target;
}
var _excluded = ["::before", "::after"];
const _excluded$1 = ["::before", "::after"];
function createStyleString(ruleName, options) {
var _createStyleObject = createStyleObject(options),
beforePseudo = _createStyleObject['::before'],
afterPseudo = _createStyleObject['::after'],
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded);
const _createStyleObject = createStyleObject(options),
{
'::before': beforePseudo,
'::after': afterPseudo
} = _createStyleObject,
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded$1);
const objToCSSRules = (stylesObj, psuedoName) => "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(property => " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'))).join(';\n'), ";\n}");
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
}
var objToCSSRules = function objToCSSRules(stylesObj, psuedoName) {
return "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(function (property) {
return " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'));
}).join(';\n'), ";\n}");
const getCapHeight = _ref => {
let {
fontSize,
fontMetrics
} = _ref;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
};
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
var getCapHeight = function getCapHeight(_ref) {
var fontSize = _ref.fontSize,
fontMetrics = _ref.fontMetrics;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
function _wrapRegExp() {
_wrapRegExp = function (re, groups) {
return new BabelRegExp(re, void 0, groups);
};
var _super = RegExp.prototype,
_groups = new WeakMap();
function BabelRegExp(re, flags, groups) {
var _this = new RegExp(re, flags);
return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype);
}
function buildGroups(result, re) {
var g = _groups.get(re);
return Object.keys(g).reduce(function (groups, name) {
var i = g[name];
if ("number" == typeof i) groups[name] = result[i];else {
for (var k = 0; void 0 === result[i[k]] && k + 1 < i.length;) k++;
groups[name] = result[i[k]];
}
return groups;
}, Object.create(null));
}
return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) {
var result = _super.exec.call(this, str);
return result && (result.groups = buildGroups(result, this)), result;
}, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
if ("string" == typeof substitution) {
var groups = _groups.get(this);
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
return "$" + groups[name];
}));
}
if ("function" == typeof substitution) {
var _this = this;
return _super[Symbol.replace].call(this, str, function () {
var args = arguments;
return "object" != typeof args[args.length - 1] && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args);
});
}
return _super[Symbol.replace].call(this, str, substitution);
}, _wrapRegExp.apply(this, arguments);
}
const _excluded = ["fontFamily", "src"];
const toPercentString = value => "".concat(round(value * 100), "%");
const toCssProperty = property => property.replace(/([A-Z])/g, property => "-".concat(property.toLowerCase()));
const calculateOverrideValues = _ref => {
let {
metrics,
fallbackMetrics
} = _ref;
// Calculate size adjust
const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm;
const fallbackFontXAvgRatio = fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm;
const sizeAdjust = preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1;
const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust;
// Calculate metric overrides for preferred font
const ascentOverride = metrics.ascent / adjustedEmSquare;
const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare;
const lineGapOverride = metrics.lineGap / adjustedEmSquare;
// Conditionally populate font face properties and format to percent
const fontFace = {};
if (ascentOverride) {
fontFace['ascentOverride'] = toPercentString(ascentOverride);
}
if (descentOverride) {
fontFace['descentOverride'] = toPercentString(descentOverride);
}
if (lineGapOverride) {
fontFace['lineGapOverride'] = toPercentString(lineGapOverride);
}
if (sizeAdjust && sizeAdjust !== 1) {
fontFace['sizeAdjust'] = toPercentString(sizeAdjust);
}
return fontFace;
};
const quoteIfNeeded = name => {
var _quotedMatch$groups;
const quotedMatch = name.match( /*#__PURE__*/_wrapRegExp(/^['"](.*)['"]$/, {
name: 1
}));
if (quotedMatch && (_quotedMatch$groups = quotedMatch.groups) !== null && _quotedMatch$groups !== void 0 && _quotedMatch$groups.name) {
// Escape double quotes in middle of name
return "\"".concat(quotedMatch.groups.name.split("\"").join("\""), "\"");
}
if (/^"/.test(name)) {
// Complete double quotes if incomplete and escape double quotes in middle
const [, ...restName] = name;
return "\"".concat(restName.map(x => x === "\"" ? "\"" : x).join(''), "\"");
}
if (!/^[a-zA-Z\d\-_]+$/.test(name)) {
// Wrap in quotes if contains any characters that are not letters,
// numbers, hyphens or underscores
return "\"".concat(name.split("\"").join("\""), "\"");
}
return name;
};
const toCssString = fontFaces => {
return fontFaces.map(_ref2 => {
let {
'@font-face': {
fontFamily,
src
}
} = _ref2,
restFontFaceProperties = _objectWithoutProperties(_ref2['@font-face'], _excluded);
const fontFace = ['@font-face {', " font-family: ".concat(quoteIfNeeded(fontFamily), ";"), " src: ".concat(src, ";")];
Object.keys(restFontFaceProperties).forEach(property => {
fontFace.push(" ".concat(toCssProperty(property), ": ").concat(restFontFaceProperties[property], ";"));
});
fontFace.push('}');
return fontFace.join('\n');
}).join('\n');
};
function createFontStack(_ref3) {
let [metrics, ...fallbackMetrics] = _ref3;
let optionsArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const {
fontFaceFormat,
fontFaceProperties
} = _objectSpread2({
fontFaceFormat: 'styleString'
}, optionsArg);
const {
familyName
} = metrics;
const fontFamilies = [quoteIfNeeded(familyName)];
const fontFaces = [];
fallbackMetrics.forEach(fallback => {
const fontFamily = "".concat(familyName, " Fallback").concat(fallbackMetrics.length > 1 ? ": ".concat(fallback.familyName) : '');
fontFamilies.push(quoteIfNeeded(fontFamily));
fontFaces.push({
'@font-face': _objectSpread2(_objectSpread2(_objectSpread2({}, fontFaceProperties), {}, {
fontFamily,
src: "local('".concat(fallback.familyName, "')")
}, calculateOverrideValues({
metrics,
fallbackMetrics: fallback
})), fontFaceProperties !== null && fontFaceProperties !== void 0 && fontFaceProperties.sizeAdjust ? {
sizeAdjust: fontFaceProperties.sizeAdjust
} : {})
});
});
return {
fontFamily: fontFamilies.join(', '),
fontFaces: {
styleString: toCssString(fontFaces),
styleObject: fontFaces
}[fontFaceFormat]
};
}
exports.createFontStack = createFontStack;
exports.createStyleObject = createStyleObject;

@@ -186,0 +385,0 @@ exports.createStyleString = createStyleString;

@@ -5,12 +5,11 @@ function normaliseOptions(options) {

}
if ('capHeight' in options && 'fontSize' in options) {
throw new Error('Please pass either `capHeight` OR `fontSize`, not both.');
}
var fontMetrics = options.fontMetrics;
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var specifiedFontSize;
var specifiedCapHeight;
const {
fontMetrics
} = options;
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
let specifiedFontSize;
let specifiedCapHeight;
if ('capHeight' in options) {

@@ -25,5 +24,3 @@ specifiedFontSize = options.capHeight / capHeightScale;

}
var specifiedLineHeight;
let specifiedLineHeight;
if ('lineGap' in options) {

@@ -34,7 +31,6 @@ specifiedLineHeight = specifiedCapHeight + options.lineGap;

}
return {
fontSize: specifiedFontSize,
lineHeight: specifiedLineHeight,
fontMetrics: fontMetrics
fontMetrics
};

@@ -50,32 +46,27 @@ }

*/
var round = function round(value) {
return parseFloat(value.toFixed(4));
};
const round = value => parseFloat(value.toFixed(4));
function precomputeValues(options) {
var _normaliseOptions = normaliseOptions(options),
fontSize = _normaliseOptions.fontSize,
lineHeight = _normaliseOptions.lineHeight,
fontMetrics = _normaliseOptions.fontMetrics;
var absoluteDescent = Math.abs(fontMetrics.descent);
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var descentScale = absoluteDescent / fontMetrics.unitsPerEm;
var ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
var lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
var contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
var lineHeightScale = contentArea / fontMetrics.unitsPerEm;
var lineHeightNormal = lineHeightScale * fontSize;
var allowForLineHeight = function allowForLineHeight(trim) {
const {
fontSize,
lineHeight,
fontMetrics
} = normaliseOptions(options);
const absoluteDescent = Math.abs(fontMetrics.descent);
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
const descentScale = absoluteDescent / fontMetrics.unitsPerEm;
const ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
const lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
const contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
const lineHeightScale = contentArea / fontMetrics.unitsPerEm;
const lineHeightNormal = lineHeightScale * fontSize;
const allowForLineHeight = trim => {
if (lineHeight) {
var specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
const specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
return trim - specifiedLineHeightOffset / fontSize;
}
return trim;
};
var capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
var baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
const capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
const baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
return {

@@ -89,10 +80,12 @@ fontSize: "".concat(round(fontSize), "px"),

var _createStyleObject = function _createStyleObject(_ref) {
var lineHeight = _ref.lineHeight,
fontSize = _ref.fontSize,
capHeightTrim = _ref.capHeightTrim,
baselineTrim = _ref.baselineTrim;
const _createStyleObject = _ref => {
let {
lineHeight,
fontSize,
capHeightTrim,
baselineTrim
} = _ref;
return {
fontSize: fontSize,
lineHeight: lineHeight,
fontSize,
lineHeight,
'::before': {

@@ -110,3 +103,2 @@ content: "''",

};
function createStyleObject(args) {

@@ -116,3 +108,2 @@ if ('capHeightTrim' in args) {

}
return _createStyleObject(precomputeValues(args));

@@ -126,3 +117,2 @@ }

var key, i;
for (i = 0; i < sourceKeys.length; i++) {

@@ -133,3 +123,2 @@ key = sourceKeys[i];

}
return target;

@@ -142,6 +131,4 @@ }

var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {

@@ -154,28 +141,239 @@ key = sourceSymbolKeys[i];

}
return target;
}
var _excluded = ["::before", "::after"];
const _excluded$1 = ["::before", "::after"];
function createStyleString(ruleName, options) {
var _createStyleObject = createStyleObject(options),
beforePseudo = _createStyleObject['::before'],
afterPseudo = _createStyleObject['::after'],
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded);
const _createStyleObject = createStyleObject(options),
{
'::before': beforePseudo,
'::after': afterPseudo
} = _createStyleObject,
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded$1);
const objToCSSRules = (stylesObj, psuedoName) => "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(property => " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'))).join(';\n'), ";\n}");
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
}
var objToCSSRules = function objToCSSRules(stylesObj, psuedoName) {
return "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(function (property) {
return " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'));
}).join(';\n'), ";\n}");
const getCapHeight = _ref => {
let {
fontSize,
fontMetrics
} = _ref;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
};
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
var getCapHeight = function getCapHeight(_ref) {
var fontSize = _ref.fontSize,
fontMetrics = _ref.fontMetrics;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
function _wrapRegExp() {
_wrapRegExp = function (re, groups) {
return new BabelRegExp(re, void 0, groups);
};
var _super = RegExp.prototype,
_groups = new WeakMap();
function BabelRegExp(re, flags, groups) {
var _this = new RegExp(re, flags);
return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype);
}
function buildGroups(result, re) {
var g = _groups.get(re);
return Object.keys(g).reduce(function (groups, name) {
var i = g[name];
if ("number" == typeof i) groups[name] = result[i];else {
for (var k = 0; void 0 === result[i[k]] && k + 1 < i.length;) k++;
groups[name] = result[i[k]];
}
return groups;
}, Object.create(null));
}
return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) {
var result = _super.exec.call(this, str);
return result && (result.groups = buildGroups(result, this)), result;
}, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
if ("string" == typeof substitution) {
var groups = _groups.get(this);
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
return "$" + groups[name];
}));
}
if ("function" == typeof substitution) {
var _this = this;
return _super[Symbol.replace].call(this, str, function () {
var args = arguments;
return "object" != typeof args[args.length - 1] && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args);
});
}
return _super[Symbol.replace].call(this, str, substitution);
}, _wrapRegExp.apply(this, arguments);
}
const _excluded = ["fontFamily", "src"];
const toPercentString = value => "".concat(round(value * 100), "%");
const toCssProperty = property => property.replace(/([A-Z])/g, property => "-".concat(property.toLowerCase()));
const calculateOverrideValues = _ref => {
let {
metrics,
fallbackMetrics
} = _ref;
// Calculate size adjust
const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm;
const fallbackFontXAvgRatio = fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm;
const sizeAdjust = preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1;
const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust;
// Calculate metric overrides for preferred font
const ascentOverride = metrics.ascent / adjustedEmSquare;
const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare;
const lineGapOverride = metrics.lineGap / adjustedEmSquare;
// Conditionally populate font face properties and format to percent
const fontFace = {};
if (ascentOverride) {
fontFace['ascentOverride'] = toPercentString(ascentOverride);
}
if (descentOverride) {
fontFace['descentOverride'] = toPercentString(descentOverride);
}
if (lineGapOverride) {
fontFace['lineGapOverride'] = toPercentString(lineGapOverride);
}
if (sizeAdjust && sizeAdjust !== 1) {
fontFace['sizeAdjust'] = toPercentString(sizeAdjust);
}
return fontFace;
};
const quoteIfNeeded = name => {
var _quotedMatch$groups;
const quotedMatch = name.match( /*#__PURE__*/_wrapRegExp(/^['"](.*)['"]$/, {
name: 1
}));
if (quotedMatch && (_quotedMatch$groups = quotedMatch.groups) !== null && _quotedMatch$groups !== void 0 && _quotedMatch$groups.name) {
// Escape double quotes in middle of name
return "\"".concat(quotedMatch.groups.name.split("\"").join("\""), "\"");
}
if (/^"/.test(name)) {
// Complete double quotes if incomplete and escape double quotes in middle
const [, ...restName] = name;
return "\"".concat(restName.map(x => x === "\"" ? "\"" : x).join(''), "\"");
}
if (!/^[a-zA-Z\d\-_]+$/.test(name)) {
// Wrap in quotes if contains any characters that are not letters,
// numbers, hyphens or underscores
return "\"".concat(name.split("\"").join("\""), "\"");
}
return name;
};
const toCssString = fontFaces => {
return fontFaces.map(_ref2 => {
let {
'@font-face': {
fontFamily,
src
}
} = _ref2,
restFontFaceProperties = _objectWithoutProperties(_ref2['@font-face'], _excluded);
const fontFace = ['@font-face {', " font-family: ".concat(quoteIfNeeded(fontFamily), ";"), " src: ".concat(src, ";")];
Object.keys(restFontFaceProperties).forEach(property => {
fontFace.push(" ".concat(toCssProperty(property), ": ").concat(restFontFaceProperties[property], ";"));
});
fontFace.push('}');
return fontFace.join('\n');
}).join('\n');
};
function createFontStack(_ref3) {
let [metrics, ...fallbackMetrics] = _ref3;
let optionsArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const {
fontFaceFormat,
fontFaceProperties
} = _objectSpread2({
fontFaceFormat: 'styleString'
}, optionsArg);
const {
familyName
} = metrics;
const fontFamilies = [quoteIfNeeded(familyName)];
const fontFaces = [];
fallbackMetrics.forEach(fallback => {
const fontFamily = "".concat(familyName, " Fallback").concat(fallbackMetrics.length > 1 ? ": ".concat(fallback.familyName) : '');
fontFamilies.push(quoteIfNeeded(fontFamily));
fontFaces.push({
'@font-face': _objectSpread2(_objectSpread2(_objectSpread2({}, fontFaceProperties), {}, {
fontFamily,
src: "local('".concat(fallback.familyName, "')")
}, calculateOverrideValues({
metrics,
fallbackMetrics: fallback
})), fontFaceProperties !== null && fontFaceProperties !== void 0 && fontFaceProperties.sizeAdjust ? {
sizeAdjust: fontFaceProperties.sizeAdjust
} : {})
});
});
return {
fontFamily: fontFamilies.join(', '),
fontFaces: {
styleString: toCssString(fontFaces),
styleObject: fontFaces
}[fontFaceFormat]
};
}
export { createStyleObject, createStyleString, getCapHeight, precomputeValues };
export { createFontStack, createStyleObject, createStyleString, getCapHeight, precomputeValues };

@@ -9,12 +9,11 @@ 'use strict';

}
if ('capHeight' in options && 'fontSize' in options) {
throw new Error('Please pass either `capHeight` OR `fontSize`, not both.');
}
var fontMetrics = options.fontMetrics;
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var specifiedFontSize;
var specifiedCapHeight;
const {
fontMetrics
} = options;
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
let specifiedFontSize;
let specifiedCapHeight;
if ('capHeight' in options) {

@@ -29,5 +28,3 @@ specifiedFontSize = options.capHeight / capHeightScale;

}
var specifiedLineHeight;
let specifiedLineHeight;
if ('lineGap' in options) {

@@ -38,7 +35,6 @@ specifiedLineHeight = specifiedCapHeight + options.lineGap;

}
return {
fontSize: specifiedFontSize,
lineHeight: specifiedLineHeight,
fontMetrics: fontMetrics
fontMetrics
};

@@ -54,32 +50,27 @@ }

*/
var round = function round(value) {
return parseFloat(value.toFixed(4));
};
const round = value => parseFloat(value.toFixed(4));
function precomputeValues(options) {
var _normaliseOptions = normaliseOptions(options),
fontSize = _normaliseOptions.fontSize,
lineHeight = _normaliseOptions.lineHeight,
fontMetrics = _normaliseOptions.fontMetrics;
var absoluteDescent = Math.abs(fontMetrics.descent);
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var descentScale = absoluteDescent / fontMetrics.unitsPerEm;
var ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
var lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
var contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
var lineHeightScale = contentArea / fontMetrics.unitsPerEm;
var lineHeightNormal = lineHeightScale * fontSize;
var allowForLineHeight = function allowForLineHeight(trim) {
const {
fontSize,
lineHeight,
fontMetrics
} = normaliseOptions(options);
const absoluteDescent = Math.abs(fontMetrics.descent);
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
const descentScale = absoluteDescent / fontMetrics.unitsPerEm;
const ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
const lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
const contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
const lineHeightScale = contentArea / fontMetrics.unitsPerEm;
const lineHeightNormal = lineHeightScale * fontSize;
const allowForLineHeight = trim => {
if (lineHeight) {
var specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
const specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
return trim - specifiedLineHeightOffset / fontSize;
}
return trim;
};
var capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
var baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
const capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
const baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
return {

@@ -93,10 +84,12 @@ fontSize: "".concat(round(fontSize), "px"),

var _createStyleObject = function _createStyleObject(_ref) {
var lineHeight = _ref.lineHeight,
fontSize = _ref.fontSize,
capHeightTrim = _ref.capHeightTrim,
baselineTrim = _ref.baselineTrim;
const _createStyleObject = _ref => {
let {
lineHeight,
fontSize,
capHeightTrim,
baselineTrim
} = _ref;
return {
fontSize: fontSize,
lineHeight: lineHeight,
fontSize,
lineHeight,
'::before': {

@@ -114,3 +107,2 @@ content: "''",

};
function createStyleObject(args) {

@@ -120,3 +112,2 @@ if ('capHeightTrim' in args) {

}
return _createStyleObject(precomputeValues(args));

@@ -130,3 +121,2 @@ }

var key, i;
for (i = 0; i < sourceKeys.length; i++) {

@@ -137,3 +127,2 @@ key = sourceKeys[i];

}
return target;

@@ -146,6 +135,4 @@ }

var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {

@@ -158,28 +145,240 @@ key = sourceSymbolKeys[i];

}
return target;
}
var _excluded = ["::before", "::after"];
const _excluded$1 = ["::before", "::after"];
function createStyleString(ruleName, options) {
var _createStyleObject = createStyleObject(options),
beforePseudo = _createStyleObject['::before'],
afterPseudo = _createStyleObject['::after'],
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded);
const _createStyleObject = createStyleObject(options),
{
'::before': beforePseudo,
'::after': afterPseudo
} = _createStyleObject,
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded$1);
const objToCSSRules = (stylesObj, psuedoName) => "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(property => " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'))).join(';\n'), ";\n}");
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
}
var objToCSSRules = function objToCSSRules(stylesObj, psuedoName) {
return "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(function (property) {
return " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'));
}).join(';\n'), ";\n}");
const getCapHeight = _ref => {
let {
fontSize,
fontMetrics
} = _ref;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
};
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
var getCapHeight = function getCapHeight(_ref) {
var fontSize = _ref.fontSize,
fontMetrics = _ref.fontMetrics;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
function _wrapRegExp() {
_wrapRegExp = function (re, groups) {
return new BabelRegExp(re, void 0, groups);
};
var _super = RegExp.prototype,
_groups = new WeakMap();
function BabelRegExp(re, flags, groups) {
var _this = new RegExp(re, flags);
return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype);
}
function buildGroups(result, re) {
var g = _groups.get(re);
return Object.keys(g).reduce(function (groups, name) {
var i = g[name];
if ("number" == typeof i) groups[name] = result[i];else {
for (var k = 0; void 0 === result[i[k]] && k + 1 < i.length;) k++;
groups[name] = result[i[k]];
}
return groups;
}, Object.create(null));
}
return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) {
var result = _super.exec.call(this, str);
return result && (result.groups = buildGroups(result, this)), result;
}, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
if ("string" == typeof substitution) {
var groups = _groups.get(this);
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
return "$" + groups[name];
}));
}
if ("function" == typeof substitution) {
var _this = this;
return _super[Symbol.replace].call(this, str, function () {
var args = arguments;
return "object" != typeof args[args.length - 1] && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args);
});
}
return _super[Symbol.replace].call(this, str, substitution);
}, _wrapRegExp.apply(this, arguments);
}
const _excluded = ["fontFamily", "src"];
const toPercentString = value => "".concat(round(value * 100), "%");
const toCssProperty = property => property.replace(/([A-Z])/g, property => "-".concat(property.toLowerCase()));
const calculateOverrideValues = _ref => {
let {
metrics,
fallbackMetrics
} = _ref;
// Calculate size adjust
const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm;
const fallbackFontXAvgRatio = fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm;
const sizeAdjust = preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1;
const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust;
// Calculate metric overrides for preferred font
const ascentOverride = metrics.ascent / adjustedEmSquare;
const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare;
const lineGapOverride = metrics.lineGap / adjustedEmSquare;
// Conditionally populate font face properties and format to percent
const fontFace = {};
if (ascentOverride) {
fontFace['ascentOverride'] = toPercentString(ascentOverride);
}
if (descentOverride) {
fontFace['descentOverride'] = toPercentString(descentOverride);
}
if (lineGapOverride) {
fontFace['lineGapOverride'] = toPercentString(lineGapOverride);
}
if (sizeAdjust && sizeAdjust !== 1) {
fontFace['sizeAdjust'] = toPercentString(sizeAdjust);
}
return fontFace;
};
const quoteIfNeeded = name => {
var _quotedMatch$groups;
const quotedMatch = name.match( /*#__PURE__*/_wrapRegExp(/^['"](.*)['"]$/, {
name: 1
}));
if (quotedMatch && (_quotedMatch$groups = quotedMatch.groups) !== null && _quotedMatch$groups !== void 0 && _quotedMatch$groups.name) {
// Escape double quotes in middle of name
return "\"".concat(quotedMatch.groups.name.split("\"").join("\""), "\"");
}
if (/^"/.test(name)) {
// Complete double quotes if incomplete and escape double quotes in middle
const [, ...restName] = name;
return "\"".concat(restName.map(x => x === "\"" ? "\"" : x).join(''), "\"");
}
if (!/^[a-zA-Z\d\-_]+$/.test(name)) {
// Wrap in quotes if contains any characters that are not letters,
// numbers, hyphens or underscores
return "\"".concat(name.split("\"").join("\""), "\"");
}
return name;
};
const toCssString = fontFaces => {
return fontFaces.map(_ref2 => {
let {
'@font-face': {
fontFamily,
src
}
} = _ref2,
restFontFaceProperties = _objectWithoutProperties(_ref2['@font-face'], _excluded);
const fontFace = ['@font-face {', " font-family: ".concat(quoteIfNeeded(fontFamily), ";"), " src: ".concat(src, ";")];
Object.keys(restFontFaceProperties).forEach(property => {
fontFace.push(" ".concat(toCssProperty(property), ": ").concat(restFontFaceProperties[property], ";"));
});
fontFace.push('}');
return fontFace.join('\n');
}).join('\n');
};
function createFontStack(_ref3) {
let [metrics, ...fallbackMetrics] = _ref3;
let optionsArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const {
fontFaceFormat,
fontFaceProperties
} = _objectSpread2({
fontFaceFormat: 'styleString'
}, optionsArg);
const {
familyName
} = metrics;
const fontFamilies = [quoteIfNeeded(familyName)];
const fontFaces = [];
fallbackMetrics.forEach(fallback => {
const fontFamily = "".concat(familyName, " Fallback").concat(fallbackMetrics.length > 1 ? ": ".concat(fallback.familyName) : '');
fontFamilies.push(quoteIfNeeded(fontFamily));
fontFaces.push({
'@font-face': _objectSpread2(_objectSpread2(_objectSpread2({}, fontFaceProperties), {}, {
fontFamily,
src: "local('".concat(fallback.familyName, "')")
}, calculateOverrideValues({
metrics,
fallbackMetrics: fallback
})), fontFaceProperties !== null && fontFaceProperties !== void 0 && fontFaceProperties.sizeAdjust ? {
sizeAdjust: fontFaceProperties.sizeAdjust
} : {})
});
});
return {
fontFamily: fontFamilies.join(', '),
fontFaces: {
styleString: toCssString(fontFaces),
styleObject: fontFaces
}[fontFaceFormat]
};
}
exports.createFontStack = createFontStack;
exports.createStyleObject = createStyleObject;

@@ -186,0 +385,0 @@ exports.createStyleString = createStyleString;

@@ -9,12 +9,11 @@ 'use strict';

}
if ('capHeight' in options && 'fontSize' in options) {
throw new Error('Please pass either `capHeight` OR `fontSize`, not both.');
}
var fontMetrics = options.fontMetrics;
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var specifiedFontSize;
var specifiedCapHeight;
const {
fontMetrics
} = options;
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
let specifiedFontSize;
let specifiedCapHeight;
if ('capHeight' in options) {

@@ -29,5 +28,3 @@ specifiedFontSize = options.capHeight / capHeightScale;

}
var specifiedLineHeight;
let specifiedLineHeight;
if ('lineGap' in options) {

@@ -38,7 +35,6 @@ specifiedLineHeight = specifiedCapHeight + options.lineGap;

}
return {
fontSize: specifiedFontSize,
lineHeight: specifiedLineHeight,
fontMetrics: fontMetrics
fontMetrics
};

@@ -54,32 +50,27 @@ }

*/
var round = function round(value) {
return parseFloat(value.toFixed(4));
};
const round = value => parseFloat(value.toFixed(4));
function precomputeValues(options) {
var _normaliseOptions = normaliseOptions(options),
fontSize = _normaliseOptions.fontSize,
lineHeight = _normaliseOptions.lineHeight,
fontMetrics = _normaliseOptions.fontMetrics;
var absoluteDescent = Math.abs(fontMetrics.descent);
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var descentScale = absoluteDescent / fontMetrics.unitsPerEm;
var ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
var lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
var contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
var lineHeightScale = contentArea / fontMetrics.unitsPerEm;
var lineHeightNormal = lineHeightScale * fontSize;
var allowForLineHeight = function allowForLineHeight(trim) {
const {
fontSize,
lineHeight,
fontMetrics
} = normaliseOptions(options);
const absoluteDescent = Math.abs(fontMetrics.descent);
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
const descentScale = absoluteDescent / fontMetrics.unitsPerEm;
const ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
const lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
const contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
const lineHeightScale = contentArea / fontMetrics.unitsPerEm;
const lineHeightNormal = lineHeightScale * fontSize;
const allowForLineHeight = trim => {
if (lineHeight) {
var specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
const specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
return trim - specifiedLineHeightOffset / fontSize;
}
return trim;
};
var capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
var baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
const capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
const baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
return {

@@ -93,10 +84,12 @@ fontSize: "".concat(round(fontSize), "px"),

var _createStyleObject = function _createStyleObject(_ref) {
var lineHeight = _ref.lineHeight,
fontSize = _ref.fontSize,
capHeightTrim = _ref.capHeightTrim,
baselineTrim = _ref.baselineTrim;
const _createStyleObject = _ref => {
let {
lineHeight,
fontSize,
capHeightTrim,
baselineTrim
} = _ref;
return {
fontSize: fontSize,
lineHeight: lineHeight,
fontSize,
lineHeight,
'::before': {

@@ -114,3 +107,2 @@ content: "''",

};
function createStyleObject(args) {

@@ -120,3 +112,2 @@ if ('capHeightTrim' in args) {

}
return _createStyleObject(precomputeValues(args));

@@ -130,3 +121,2 @@ }

var key, i;
for (i = 0; i < sourceKeys.length; i++) {

@@ -137,3 +127,2 @@ key = sourceKeys[i];

}
return target;

@@ -146,6 +135,4 @@ }

var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {

@@ -158,28 +145,240 @@ key = sourceSymbolKeys[i];

}
return target;
}
var _excluded = ["::before", "::after"];
const _excluded$1 = ["::before", "::after"];
function createStyleString(ruleName, options) {
var _createStyleObject = createStyleObject(options),
beforePseudo = _createStyleObject['::before'],
afterPseudo = _createStyleObject['::after'],
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded);
const _createStyleObject = createStyleObject(options),
{
'::before': beforePseudo,
'::after': afterPseudo
} = _createStyleObject,
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded$1);
const objToCSSRules = (stylesObj, psuedoName) => "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(property => " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'))).join(';\n'), ";\n}");
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
}
var objToCSSRules = function objToCSSRules(stylesObj, psuedoName) {
return "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(function (property) {
return " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'));
}).join(';\n'), ";\n}");
const getCapHeight = _ref => {
let {
fontSize,
fontMetrics
} = _ref;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
};
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
var getCapHeight = function getCapHeight(_ref) {
var fontSize = _ref.fontSize,
fontMetrics = _ref.fontMetrics;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
function _wrapRegExp() {
_wrapRegExp = function (re, groups) {
return new BabelRegExp(re, void 0, groups);
};
var _super = RegExp.prototype,
_groups = new WeakMap();
function BabelRegExp(re, flags, groups) {
var _this = new RegExp(re, flags);
return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype);
}
function buildGroups(result, re) {
var g = _groups.get(re);
return Object.keys(g).reduce(function (groups, name) {
var i = g[name];
if ("number" == typeof i) groups[name] = result[i];else {
for (var k = 0; void 0 === result[i[k]] && k + 1 < i.length;) k++;
groups[name] = result[i[k]];
}
return groups;
}, Object.create(null));
}
return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) {
var result = _super.exec.call(this, str);
return result && (result.groups = buildGroups(result, this)), result;
}, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
if ("string" == typeof substitution) {
var groups = _groups.get(this);
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
return "$" + groups[name];
}));
}
if ("function" == typeof substitution) {
var _this = this;
return _super[Symbol.replace].call(this, str, function () {
var args = arguments;
return "object" != typeof args[args.length - 1] && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args);
});
}
return _super[Symbol.replace].call(this, str, substitution);
}, _wrapRegExp.apply(this, arguments);
}
const _excluded = ["fontFamily", "src"];
const toPercentString = value => "".concat(round(value * 100), "%");
const toCssProperty = property => property.replace(/([A-Z])/g, property => "-".concat(property.toLowerCase()));
const calculateOverrideValues = _ref => {
let {
metrics,
fallbackMetrics
} = _ref;
// Calculate size adjust
const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm;
const fallbackFontXAvgRatio = fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm;
const sizeAdjust = preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1;
const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust;
// Calculate metric overrides for preferred font
const ascentOverride = metrics.ascent / adjustedEmSquare;
const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare;
const lineGapOverride = metrics.lineGap / adjustedEmSquare;
// Conditionally populate font face properties and format to percent
const fontFace = {};
if (ascentOverride) {
fontFace['ascentOverride'] = toPercentString(ascentOverride);
}
if (descentOverride) {
fontFace['descentOverride'] = toPercentString(descentOverride);
}
if (lineGapOverride) {
fontFace['lineGapOverride'] = toPercentString(lineGapOverride);
}
if (sizeAdjust && sizeAdjust !== 1) {
fontFace['sizeAdjust'] = toPercentString(sizeAdjust);
}
return fontFace;
};
const quoteIfNeeded = name => {
var _quotedMatch$groups;
const quotedMatch = name.match( /*#__PURE__*/_wrapRegExp(/^['"](.*)['"]$/, {
name: 1
}));
if (quotedMatch && (_quotedMatch$groups = quotedMatch.groups) !== null && _quotedMatch$groups !== void 0 && _quotedMatch$groups.name) {
// Escape double quotes in middle of name
return "\"".concat(quotedMatch.groups.name.split("\"").join("\""), "\"");
}
if (/^"/.test(name)) {
// Complete double quotes if incomplete and escape double quotes in middle
const [, ...restName] = name;
return "\"".concat(restName.map(x => x === "\"" ? "\"" : x).join(''), "\"");
}
if (!/^[a-zA-Z\d\-_]+$/.test(name)) {
// Wrap in quotes if contains any characters that are not letters,
// numbers, hyphens or underscores
return "\"".concat(name.split("\"").join("\""), "\"");
}
return name;
};
const toCssString = fontFaces => {
return fontFaces.map(_ref2 => {
let {
'@font-face': {
fontFamily,
src
}
} = _ref2,
restFontFaceProperties = _objectWithoutProperties(_ref2['@font-face'], _excluded);
const fontFace = ['@font-face {', " font-family: ".concat(quoteIfNeeded(fontFamily), ";"), " src: ".concat(src, ";")];
Object.keys(restFontFaceProperties).forEach(property => {
fontFace.push(" ".concat(toCssProperty(property), ": ").concat(restFontFaceProperties[property], ";"));
});
fontFace.push('}');
return fontFace.join('\n');
}).join('\n');
};
function createFontStack(_ref3) {
let [metrics, ...fallbackMetrics] = _ref3;
let optionsArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const {
fontFaceFormat,
fontFaceProperties
} = _objectSpread2({
fontFaceFormat: 'styleString'
}, optionsArg);
const {
familyName
} = metrics;
const fontFamilies = [quoteIfNeeded(familyName)];
const fontFaces = [];
fallbackMetrics.forEach(fallback => {
const fontFamily = "".concat(familyName, " Fallback").concat(fallbackMetrics.length > 1 ? ": ".concat(fallback.familyName) : '');
fontFamilies.push(quoteIfNeeded(fontFamily));
fontFaces.push({
'@font-face': _objectSpread2(_objectSpread2(_objectSpread2({}, fontFaceProperties), {}, {
fontFamily,
src: "local('".concat(fallback.familyName, "')")
}, calculateOverrideValues({
metrics,
fallbackMetrics: fallback
})), fontFaceProperties !== null && fontFaceProperties !== void 0 && fontFaceProperties.sizeAdjust ? {
sizeAdjust: fontFaceProperties.sizeAdjust
} : {})
});
});
return {
fontFamily: fontFamilies.join(', '),
fontFaces: {
styleString: toCssString(fontFaces),
styleObject: fontFaces
}[fontFaceFormat]
};
}
exports.createFontStack = createFontStack;
exports.createStyleObject = createStyleObject;

@@ -186,0 +385,0 @@ exports.createStyleString = createStyleString;

@@ -5,12 +5,11 @@ function normaliseOptions(options) {

}
if ('capHeight' in options && 'fontSize' in options) {
throw new Error('Please pass either `capHeight` OR `fontSize`, not both.');
}
var fontMetrics = options.fontMetrics;
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var specifiedFontSize;
var specifiedCapHeight;
const {
fontMetrics
} = options;
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
let specifiedFontSize;
let specifiedCapHeight;
if ('capHeight' in options) {

@@ -25,5 +24,3 @@ specifiedFontSize = options.capHeight / capHeightScale;

}
var specifiedLineHeight;
let specifiedLineHeight;
if ('lineGap' in options) {

@@ -34,7 +31,6 @@ specifiedLineHeight = specifiedCapHeight + options.lineGap;

}
return {
fontSize: specifiedFontSize,
lineHeight: specifiedLineHeight,
fontMetrics: fontMetrics
fontMetrics
};

@@ -50,32 +46,27 @@ }

*/
var round = function round(value) {
return parseFloat(value.toFixed(4));
};
const round = value => parseFloat(value.toFixed(4));
function precomputeValues(options) {
var _normaliseOptions = normaliseOptions(options),
fontSize = _normaliseOptions.fontSize,
lineHeight = _normaliseOptions.lineHeight,
fontMetrics = _normaliseOptions.fontMetrics;
var absoluteDescent = Math.abs(fontMetrics.descent);
var capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
var descentScale = absoluteDescent / fontMetrics.unitsPerEm;
var ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
var lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
var contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
var lineHeightScale = contentArea / fontMetrics.unitsPerEm;
var lineHeightNormal = lineHeightScale * fontSize;
var allowForLineHeight = function allowForLineHeight(trim) {
const {
fontSize,
lineHeight,
fontMetrics
} = normaliseOptions(options);
const absoluteDescent = Math.abs(fontMetrics.descent);
const capHeightScale = fontMetrics.capHeight / fontMetrics.unitsPerEm;
const descentScale = absoluteDescent / fontMetrics.unitsPerEm;
const ascentScale = fontMetrics.ascent / fontMetrics.unitsPerEm;
const lineGapScale = fontMetrics.lineGap / fontMetrics.unitsPerEm;
const contentArea = fontMetrics.ascent + fontMetrics.lineGap + absoluteDescent;
const lineHeightScale = contentArea / fontMetrics.unitsPerEm;
const lineHeightNormal = lineHeightScale * fontSize;
const allowForLineHeight = trim => {
if (lineHeight) {
var specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
const specifiedLineHeightOffset = (lineHeightNormal - lineHeight) / 2;
return trim - specifiedLineHeightOffset / fontSize;
}
return trim;
};
var capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
var baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
const capHeightTrim = allowForLineHeight(ascentScale - capHeightScale + lineGapScale / 2) * -1;
const baselineTrim = allowForLineHeight(descentScale + lineGapScale / 2) * -1;
return {

@@ -89,10 +80,12 @@ fontSize: "".concat(round(fontSize), "px"),

var _createStyleObject = function _createStyleObject(_ref) {
var lineHeight = _ref.lineHeight,
fontSize = _ref.fontSize,
capHeightTrim = _ref.capHeightTrim,
baselineTrim = _ref.baselineTrim;
const _createStyleObject = _ref => {
let {
lineHeight,
fontSize,
capHeightTrim,
baselineTrim
} = _ref;
return {
fontSize: fontSize,
lineHeight: lineHeight,
fontSize,
lineHeight,
'::before': {

@@ -110,3 +103,2 @@ content: "''",

};
function createStyleObject(args) {

@@ -116,3 +108,2 @@ if ('capHeightTrim' in args) {

}
return _createStyleObject(precomputeValues(args));

@@ -126,3 +117,2 @@ }

var key, i;
for (i = 0; i < sourceKeys.length; i++) {

@@ -133,3 +123,2 @@ key = sourceKeys[i];

}
return target;

@@ -142,6 +131,4 @@ }

var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {

@@ -154,28 +141,239 @@ key = sourceSymbolKeys[i];

}
return target;
}
var _excluded = ["::before", "::after"];
const _excluded$1 = ["::before", "::after"];
function createStyleString(ruleName, options) {
var _createStyleObject = createStyleObject(options),
beforePseudo = _createStyleObject['::before'],
afterPseudo = _createStyleObject['::after'],
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded);
const _createStyleObject = createStyleObject(options),
{
'::before': beforePseudo,
'::after': afterPseudo
} = _createStyleObject,
rootStyles = _objectWithoutProperties(_createStyleObject, _excluded$1);
const objToCSSRules = (stylesObj, psuedoName) => "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(property => " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'))).join(';\n'), ";\n}");
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
}
var objToCSSRules = function objToCSSRules(stylesObj, psuedoName) {
return "\n.".concat(ruleName).concat(psuedoName ? "::".concat(psuedoName) : '', " {\n").concat(Object.keys(stylesObj).map(function (property) {
return " ".concat(property.replace(/[A-Z]/g, '-$&').toLowerCase(), ": ").concat(stylesObj[property].replace(/'/g, '"'));
}).join(';\n'), ";\n}");
const getCapHeight = _ref => {
let {
fontSize,
fontMetrics
} = _ref;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
};
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
return [objToCSSRules(rootStyles), objToCSSRules(beforePseudo, 'before'), objToCSSRules(afterPseudo, 'after')].join('\n');
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
var getCapHeight = function getCapHeight(_ref) {
var fontSize = _ref.fontSize,
fontMetrics = _ref.fontMetrics;
return round(fontSize * fontMetrics.capHeight / fontMetrics.unitsPerEm);
function _wrapRegExp() {
_wrapRegExp = function (re, groups) {
return new BabelRegExp(re, void 0, groups);
};
var _super = RegExp.prototype,
_groups = new WeakMap();
function BabelRegExp(re, flags, groups) {
var _this = new RegExp(re, flags);
return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype);
}
function buildGroups(result, re) {
var g = _groups.get(re);
return Object.keys(g).reduce(function (groups, name) {
var i = g[name];
if ("number" == typeof i) groups[name] = result[i];else {
for (var k = 0; void 0 === result[i[k]] && k + 1 < i.length;) k++;
groups[name] = result[i[k]];
}
return groups;
}, Object.create(null));
}
return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) {
var result = _super.exec.call(this, str);
return result && (result.groups = buildGroups(result, this)), result;
}, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) {
if ("string" == typeof substitution) {
var groups = _groups.get(this);
return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) {
return "$" + groups[name];
}));
}
if ("function" == typeof substitution) {
var _this = this;
return _super[Symbol.replace].call(this, str, function () {
var args = arguments;
return "object" != typeof args[args.length - 1] && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args);
});
}
return _super[Symbol.replace].call(this, str, substitution);
}, _wrapRegExp.apply(this, arguments);
}
const _excluded = ["fontFamily", "src"];
const toPercentString = value => "".concat(round(value * 100), "%");
const toCssProperty = property => property.replace(/([A-Z])/g, property => "-".concat(property.toLowerCase()));
const calculateOverrideValues = _ref => {
let {
metrics,
fallbackMetrics
} = _ref;
// Calculate size adjust
const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm;
const fallbackFontXAvgRatio = fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm;
const sizeAdjust = preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1;
const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust;
// Calculate metric overrides for preferred font
const ascentOverride = metrics.ascent / adjustedEmSquare;
const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare;
const lineGapOverride = metrics.lineGap / adjustedEmSquare;
// Conditionally populate font face properties and format to percent
const fontFace = {};
if (ascentOverride) {
fontFace['ascentOverride'] = toPercentString(ascentOverride);
}
if (descentOverride) {
fontFace['descentOverride'] = toPercentString(descentOverride);
}
if (lineGapOverride) {
fontFace['lineGapOverride'] = toPercentString(lineGapOverride);
}
if (sizeAdjust && sizeAdjust !== 1) {
fontFace['sizeAdjust'] = toPercentString(sizeAdjust);
}
return fontFace;
};
const quoteIfNeeded = name => {
var _quotedMatch$groups;
const quotedMatch = name.match( /*#__PURE__*/_wrapRegExp(/^['"](.*)['"]$/, {
name: 1
}));
if (quotedMatch && (_quotedMatch$groups = quotedMatch.groups) !== null && _quotedMatch$groups !== void 0 && _quotedMatch$groups.name) {
// Escape double quotes in middle of name
return "\"".concat(quotedMatch.groups.name.split("\"").join("\""), "\"");
}
if (/^"/.test(name)) {
// Complete double quotes if incomplete and escape double quotes in middle
const [, ...restName] = name;
return "\"".concat(restName.map(x => x === "\"" ? "\"" : x).join(''), "\"");
}
if (!/^[a-zA-Z\d\-_]+$/.test(name)) {
// Wrap in quotes if contains any characters that are not letters,
// numbers, hyphens or underscores
return "\"".concat(name.split("\"").join("\""), "\"");
}
return name;
};
const toCssString = fontFaces => {
return fontFaces.map(_ref2 => {
let {
'@font-face': {
fontFamily,
src
}
} = _ref2,
restFontFaceProperties = _objectWithoutProperties(_ref2['@font-face'], _excluded);
const fontFace = ['@font-face {', " font-family: ".concat(quoteIfNeeded(fontFamily), ";"), " src: ".concat(src, ";")];
Object.keys(restFontFaceProperties).forEach(property => {
fontFace.push(" ".concat(toCssProperty(property), ": ").concat(restFontFaceProperties[property], ";"));
});
fontFace.push('}');
return fontFace.join('\n');
}).join('\n');
};
function createFontStack(_ref3) {
let [metrics, ...fallbackMetrics] = _ref3;
let optionsArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const {
fontFaceFormat,
fontFaceProperties
} = _objectSpread2({
fontFaceFormat: 'styleString'
}, optionsArg);
const {
familyName
} = metrics;
const fontFamilies = [quoteIfNeeded(familyName)];
const fontFaces = [];
fallbackMetrics.forEach(fallback => {
const fontFamily = "".concat(familyName, " Fallback").concat(fallbackMetrics.length > 1 ? ": ".concat(fallback.familyName) : '');
fontFamilies.push(quoteIfNeeded(fontFamily));
fontFaces.push({
'@font-face': _objectSpread2(_objectSpread2(_objectSpread2({}, fontFaceProperties), {}, {
fontFamily,
src: "local('".concat(fallback.familyName, "')")
}, calculateOverrideValues({
metrics,
fallbackMetrics: fallback
})), fontFaceProperties !== null && fontFaceProperties !== void 0 && fontFaceProperties.sizeAdjust ? {
sizeAdjust: fontFaceProperties.sizeAdjust
} : {})
});
});
return {
fontFamily: fontFamilies.join(', '),
fontFaces: {
styleString: toCssString(fontFaces),
styleObject: fontFaces
}[fontFaceFormat]
};
}
export { createStyleObject, createStyleString, getCapHeight, precomputeValues };
export { createFontStack, createStyleObject, createStyleString, getCapHeight, precomputeValues };

@@ -0,0 +0,0 @@ import type { CapsizeOptions, ComputedValues } from './types';

import { createStyleObject } from './createStyleObject';
export declare function createStyleString(ruleName: string, options: Parameters<typeof createStyleObject>[0]): string;

2

dist/declarations/src/getCapHeight.d.ts
import { FontMetrics } from './types';
export declare const getCapHeight: ({ fontSize, fontMetrics, }: {
fontSize: number;
fontMetrics: FontMetrics;
fontMetrics: Pick<FontMetrics, 'capHeight' | 'unitsPerEm'>;
}) => number;

@@ -5,2 +5,3 @@ export { createStyleObject } from './createStyleObject';

export { getCapHeight } from './getCapHeight';
export { createFontStack } from './createFontStack';
export type { FontMetrics } from './types';

@@ -5,3 +5,9 @@ import { CapsizeOptions } from './types';

lineHeight: number | undefined;
fontMetrics: import("./types").FontMetrics;
fontMetrics: {
capHeight: number;
ascent: number;
descent: number;
lineGap: number;
unitsPerEm: number;
};
};
import { ComputedValues, CapsizeOptions } from './types';
export declare function precomputeValues(options: CapsizeOptions): ComputedValues;
export declare const round: (value: number) => number;
export interface FontMetrics {
/** The font family name as authored by font creator */
familyName: string;
/**
* The style of the font: serif, sans-serif, monospace, display, or handwriting.
*
* (Optional as only availble for metrics from the `@capsizecss/metrics` package. Value not extractable from font data tables.)
*/
category?: string;
/** The height of the ascenders above baseline */
ascent: number;
/** The descent of the descenders below baseline */
descent: number;
/** The amount of space included between lines */
lineGap: number;
/** The size of the font’s internal coordinate grid */
unitsPerEm: number;
/** The height of capital letters above the baseline */
capHeight: number;
/** The height of the main body of lower case letters above baseline */
xHeight: number;
/** The average width of lowercase characters (currently derived from latin character frequencies in English language) */
xWidthAvg: number;
}

@@ -17,6 +34,7 @@ export declare type ComputedValues = {

};
declare type FontMetricsForTrim = Pick<FontMetrics, 'ascent' | 'descent' | 'capHeight' | 'lineGap' | 'unitsPerEm'>;
declare type CapHeightWithLeading = {
capHeight: number;
leading?: number;
fontMetrics: FontMetrics;
fontMetrics: FontMetricsForTrim;
} & NotComputedValues;

@@ -26,3 +44,3 @@ declare type CapHeightWithLineGap = {

lineGap: number;
fontMetrics: FontMetrics;
fontMetrics: FontMetricsForTrim;
} & NotComputedValues;

@@ -32,3 +50,3 @@ declare type FontSizeWithLeading = {

leading?: number;
fontMetrics: FontMetrics;
fontMetrics: FontMetricsForTrim;
} & Omit<NotComputedValues, 'fontSize'>;

@@ -38,5 +56,5 @@ declare type FontSizeWithLineGap = {

lineGap: number;
fontMetrics: FontMetrics;
fontMetrics: FontMetricsForTrim;
} & Omit<NotComputedValues, 'fontSize'>;
export declare type CapsizeOptions = CapHeightWithLineGap | CapHeightWithLeading | FontSizeWithLineGap | FontSizeWithLeading;
export {};
{
"name": "@capsizecss/core",
"version": "3.0.0",
"version": "3.1.0",
"description": "Flipping how we define typography",

@@ -37,9 +37,20 @@ "main": "dist/capsizecss-core.cjs.js",

"line gap",
"leading"
"leading",
"fallback font",
"font metrics",
"ascent override",
"descent override",
"line gap override",
"size adjust",
"content layout shift",
"cls"
],
"license": "MIT",
"dependencies": {},
"dependencies": {
"csstype": "^3.1.1"
},
"devDependencies": {
"@babel/core": "^7.19.6",
"@emotion/css": "^11.1.3"
}
}
}

@@ -1,4 +0,4 @@

<img src="https://raw.githubusercontent.com/seek-oss/capsize/HEAD/images/capsize-header.png" alt="Capsize" title="Capsize" width="443px" />
<img src="https://raw.githubusercontent.com/seek-oss/capsize/HEAD/images/capsize-header.png#gh-light-mode-only" alt="Capsize" title="Capsize" width="443px" />
<img src="https://raw.githubusercontent.com/seek-oss/capsize/HEAD/images/capsize-header-inverted.png#gh-dark-mode-only" alt="Capsize" title="Capsize" width="443px" />
<br/>
<br/>

@@ -9,6 +9,9 @@ > Capsize makes the sizing and layout of text as predictable as every other element on the screen.

<br/>
```bash
npm install @capsizecss/core
```
- [Installation](#installation)
- [Usage](#usage)
- [createStyleObject](#createstyleobject)
- [createStyleString](#createstylestring)
- [Options](#options)

@@ -19,19 +22,13 @@ - [Text size](#text-size)

- [Core](#core)
- [createFontStack](#createfontstack)
- [Usage in CSS stylesheet](#usage-in-css-stylesheet-or-a-style-tag)
- [Usage with CSS-in-JS frameworks](#usage-with-css-in-js-frameworks)
- [Additional `font-face` properties](#providing-additional-font-face-properties)
- [precomputeValues](#precomputevalues)
- [getCapHeight](#getcapheight)
- [Metrics](#metrics)
- [Unpack](#unpack)
- [Integrations](#integrations)
- [vanilla-extract](packages/vanilla-extract/README.md)
<br/>
## Installation
Install the core package:
```bash
npm install @capsizecss/core
```
<br/>
## Usage

@@ -61,2 +58,17 @@

Note: It is recommended that you install the [@capsizecss/metrics](packages/metrics/README.md) package and import the metrics from there:
```ts
import { createStyleObject } from '@capsizecss/core';
import arialMetrics from '@capsizecss/metrics/arial';
const capsizeStyles = createStyleObject({
fontSize: 16,
leading: 24,
fontMetrics: arialMetrics,
});
```
See the [fontMetrics](#font-metrics) option documented below for more ways to obtain these metrics.
2. Apply styles to the text element, for example via the `css` prop.

@@ -83,2 +95,3 @@

import { createStyleString } from '@capsizecss/core';
import arialMetrics from '@capsizecss/metrics/arial';

@@ -88,9 +101,3 @@ const capsizedStyleRule = createStyleString('capsizedText', {

leading: 24,
fontMetrics: {
capHeight: 700,
ascent: 1058,
descent: -291,
lineGap: 0,
unitsPerEm: 1000,
},
fontMetrics: arialMetrics,
});

@@ -112,4 +119,2 @@ ```

<br/>
## Options

@@ -155,23 +160,173 @@

This metadata is extracted from the metrics tables inside the font itself. You can use [the Capsize website](https://seek-oss.github.io/capsize/) to find these by selecting a font and referencing `Metrics` tab in step 3.
This metadata is extracted from the metrics tables inside the font itself. There are a number of ways to find this information:
<br/>
- If using a Google Font or system font, install the [@capsizecss/metrics](packages/metrics/README.md) package and import the metrics by name. For example:
```ts
import arialMetrics from '@capsizecss/metrics/arial';
```
- If using a font from a file, install the [@capsizecss/unpack](packages/unpack/README.md) package and extract the metrics from the font file directly. For example:
```ts
import { fromFile } from '@capsizecss/unpack';
const metrics = await fromFile(filePath);
```
- Or, use [the Capsize website](https://seek-oss.github.io/capsize/) to find these by selecting a font and referencing `Metrics` tab in step 3.
## Core
The core package also provides access to lower level values for a specific font and font size combination.
The core package also provides a few other metrics-based features for improving typography on the web:
### createFontStack
Creates metrics-based `@font-face` declarations to improve the alignment of font family fallbacks, which can dramatically improve the [Cumulative Layout Shift](https://web.dev/cls/) metric for sites that depend on a web font.
#### Usage
Consider the following example, where the desired web font is [Lobster](https://fonts.google.com/specimen/Lobster), falling back to `Helvetica Neue` and then `Arial`, e.g. `font-family: Lobster, 'Helvetica Neue', Arial`.
1. Import `createFontStack` from the core package:
```ts
import { createFontStack } from '@capsizecss/core';
```
2. Import the font metrics for each of the desired fonts (see [Font Metrics](#font-metrics) above):
```ts
import lobster from '@capsizecss/metrics/lobster';
import helveticaNeue from '@capsizecss/metrics/helveticaNeue';
import arial from '@capsizecss/metrics/arial';
```
3. Create your font stack passing the metrics as an array, using the same order as you would via the `font-family` CSS property.
```ts
const { fontFamily, fontFaces } = createFontStack([
lobster,
helveticaNeue,
arial,
]);
```
The returned value contains the generated font face declarations as well as the computed `fontFamily` with the appropriately ordered font aliases.
#### Usage in CSS stylesheet or a style tag
The returned values can be templated into a stylesheet or a `style` block. Here is an example [handlebars](https://handlebarsjs.com/) template:
```html
<style type="text/css">
.heading {
font-family: {{ fontFamily }}
}
{{ fontFaces }}
</style>
```
This will produce the following CSS:
```css
.heading {
font-family: Lobster, 'Lobster Fallback: Helvetica Neue',
'Lobster Fallback: Arial';
}
@font-face {
font-family: 'Lobster Fallback: Helvetica Neue';
src: local('Helvetica Neue');
ascent-override: 115.1741%;
descent-override: 28.7935%;
size-adjust: 86.8251%;
}
@font-face {
font-family: 'Lobster Fallback: Arial';
src: local('Arial');
ascent-override: 113.5679%;
descent-override: 28.392%;
size-adjust: 88.053%;
}
```
#### Usage with CSS-in-JS frameworks
If working with a CSS-in-JS library, the returned `fontFaces` can be provided as a JavaScript style object by providing `styleObject` as a `fontFaceFormat` option.
Here is an example using [Emotion](https://emotion.sh/):
```tsx
import { Global } from '@emotion/core';
const { fontFaces, fontFamily } = createFontStack(
[lobster, helveticaNeue, arial],
{
fontFaceFormat: 'styleObject',
},
);
export const App = () => (
<>
<Global styles={fontFaces} />
<p css={{ fontFamily }}>...</p>
</>
);
```
> Also useful as a source for further manipulation given it is a data structure that can be iterated over or extended.
#### Providing additional `font-face` properties
Additional properties can be added to the generated `@font-face` declarations via the `fontFaceProperties` option:
```ts
const { fontFamily, fontFaces } = createFontStack(
[lobster, helveticaNeue, arial],
{
fontFaceProperties: {
fontDisplay: 'swap',
},
},
);
```
This will result in the following additions to the declarations:
```diff
@font-face {
font-family: 'Lobster Fallback: Helvetica Neue';
src: local('Helvetica Neue');
ascent-override: 115.1741%;
descent-override: 28.7935%;
size-adjust: 86.8251%;
+ font-display: swap;
}
@font-face {
font-family: 'Lobster Fallback: Arial';
src: local('Arial');
ascent-override: 113.5679%;
descent-override: 28.392%;
size-adjust: 88.053%;
+ font-display: swap;
}
```
Worth noting, passing any of the metric override CSS properties will be ignored as they are calculated by Capsize. However, the `size-adjust` property is accepted to support fine-tuning the override for particular use cases. This can be used to finesse the adjustment for specific text, or to disable the adjustment by setting it to `100%`.
### precomputeValues
Returns all the information required to create styles for a specific font size given the provided font metrics. This is useful for integrations with different styling solutions.
Returns all the information required to create leading trim styles for a specific font size given the provided font metrics. This is useful for integrations with different styling solutions.
Accepts the same [options](#options) as [createStyleObject](#createstyleobject) and [createStyleString](#createstylestring).
```ts
import { precomputeValues } from '@capsizecss/core';
import arialMetrics from '@capsizecss/metrics/arial';
const capsizeValues = precomputeValues({
fontSize: 24,
fontMetrics: {
...
}
})
fontSize: 16,
leading: 24,
fontMetrics: arialMetrics,
});

@@ -192,9 +347,8 @@ // => {

import { getCapHeight } from '@capsizecss/core';
import arialMetrics from '@capsizecss/metrics/arial';
const actualCapHeight = getCapHeight({
fontSize: 24,
fontMetrics: {
...
}
})
fontMetrics: arialMetrics,
});

@@ -204,5 +358,22 @@ // => number

<br />
<br />
## Metrics
To make the retrieval of font metrics easy, Capsize provides the `@capsizecss/metrics` package containing all the required data for both system and Google fonts.
```bash
npm install @capsizecss/metrics
```
See the [package](packages/metrics/README.md) for documentation.
## Unpack
If you are using a custom font or one not included in the `@capsizecss/metrics` package, Capsize provides the `@capsizecss/unpack` package to extract the required data either via a URL or from a local file.
```bash
npm install @capsizecss/unpack
```
See the [package](packages/unpack/README.md) for documentation.
## Integrations

@@ -212,5 +383,2 @@

<br />
<br />
## Thanks

@@ -222,7 +390,4 @@

<br />
<br />
## License
MIT.
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