@mui/x-charts
Version:
The community edition of the charts components (MUI X).
122 lines (116 loc) • 3.75 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getStyleString = exports.getStringSize = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
// DOM utils taken from
// https://github.com/recharts/recharts/blob/master/src/util/DOMUtils.ts
const isSsr = () => !(typeof window !== 'undefined' && window.document && window.setTimeout);
const stringCache = {
widthCache: {},
cacheCount: 0
};
const MAX_CACHE_NUM = 2000;
const SPAN_STYLE = {
position: 'absolute',
top: '-20000px',
left: 0,
padding: 0,
margin: 0,
border: 'none',
whiteSpace: 'pre'
};
const STYLE_LIST = ['minWidth', 'maxWidth', 'width', 'minHeight', 'maxHeight', 'height', 'top', 'left', 'fontSize', 'padding', 'margin', 'paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom', 'marginLeft', 'marginRight', 'marginTop', 'marginBottom'];
const MEASUREMENT_SPAN_ID = 'mui_measurement_span';
/**
*
* @param name CSS property name
* @param value
* @returns add 'px' for distance properties
*/
function autoCompleteStyle(name, value) {
if (STYLE_LIST.indexOf(name) >= 0 && value === +value) {
return `${value}px`;
}
return value;
}
/**
*
* @param text camelcase css property
* @returns css property
*/
function camelToMiddleLine(text) {
const strs = text.split('');
const formatStrs = strs.reduce((result, entry) => {
if (entry === entry.toUpperCase()) {
return [...result, '-', entry.toLowerCase()];
}
return [...result, entry];
}, []);
return formatStrs.join('');
}
/**
*
* @param style React style object
* @returns CSS styling string
*/
const getStyleString = style => Object.keys(style).sort().reduce((result, s) => `${result}${camelToMiddleLine(s)}:${autoCompleteStyle(s, style[s])};`, '');
/**
*
* @param text The string to estimate
* @param style The style applied
* @returns width and height of the text
*/
exports.getStyleString = getStyleString;
const getStringSize = (text, style = {}) => {
if (text === undefined || text === null || isSsr()) {
return {
width: 0,
height: 0
};
}
const str = `${text}`;
const styleString = getStyleString(style);
const cacheKey = `${str}-${styleString}`;
if (stringCache.widthCache[cacheKey]) {
return stringCache.widthCache[cacheKey];
}
try {
let measurementSpan = document.getElementById(MEASUREMENT_SPAN_ID);
if (measurementSpan === null) {
measurementSpan = document.createElement('span');
measurementSpan.setAttribute('id', MEASUREMENT_SPAN_ID);
measurementSpan.setAttribute('aria-hidden', 'true');
document.body.appendChild(measurementSpan);
}
// Need to use CSS Object Model (CSSOM) to be able to comply with Content Security Policy (CSP)
// https://en.wikipedia.org/wiki/Content_Security_Policy
const measurementSpanStyle = (0, _extends2.default)({}, SPAN_STYLE, style);
Object.keys(measurementSpanStyle).map(styleKey => {
measurementSpan.style[camelToMiddleLine(styleKey)] = autoCompleteStyle(styleKey, measurementSpanStyle[styleKey]);
return styleKey;
});
measurementSpan.textContent = str;
const rect = measurementSpan.getBoundingClientRect();
const result = {
width: rect.width,
height: rect.height
};
stringCache.widthCache[cacheKey] = result;
if (stringCache.cacheCount + 1 > MAX_CACHE_NUM) {
stringCache.cacheCount = 0;
stringCache.widthCache = {};
} else {
stringCache.cacheCount += 1;
}
return result;
} catch (e) {
return {
width: 0,
height: 0
};
}
};
exports.getStringSize = getStringSize;
;