react-fitty
Version:

61 lines (53 loc) • 1.71 kB
JavaScript
import React from 'react';
import fitty from 'fitty';
const fullWidth = {
width: '100%'
}; // todo support style and className on Wrapper(root div) and Ref div
// one solution could be adding style prop for root and another styleProp to ref
/**
* Snugly resizes text to fit its parent container width
*/
const ReactFitty = /*#__PURE__*/React.forwardRef(function ReactFitty({
children,
minSize = 12,
maxSize = 512,
wrapText = false,
...rest
}, ref) {
const internalRef = React.useRef(null);
/**
* Need to use the correct ref because the component ref can contain a className that dynamically
* change the text size
*/
const correctRef = ref || internalRef;
React.useLayoutEffect(() => {
const effectRef = ref || internalRef;
const fitInstance = fitty(effectRef.current, {
minSize: minSize,
maxSize: maxSize,
multiLine: wrapText,
observeMutations: {
subtree: true,
childList: true,
characterData: true,
attributeFilter: ['class']
}
}); // wait browser finish text width calc with relative properties like rem and %
// then, fit text in the next animation frame
// maybe that needed to be handled in fitty?
setTimeout(() => {
fitInstance.fit();
}, 0);
return () => {
fitty(effectRef.current).unsubscribe();
};
}, []); // fitty need an extra div to avoid parent padding issue
// see https://github.com/rikschennink/fitty/issues/20
return React.createElement("div", {
style: fullWidth
}, React.createElement("div", Object.assign({}, rest, {
ref: correctRef
}), children));
});
export { ReactFitty };
//# sourceMappingURL=react-fitty.esm.js.map