malte-wessel / react-textfit

React component to fit headlines and paragraphs into elements
http://malte-wessel.github.io/react-textfit/
MIT License
469 stars 143 forks source link

Add option to match line height to font-size #55

Open tylers-username opened 4 years ago

tylers-username commented 4 years ago

Thanks for this fantastic tool!

I'm using react-textfit to implement the following: image

The problem is that I end up with a lot of spacing between each word because each one must be an individual <Textfit>. This is resolved by matching the line-height to the font-size.

A nice feature would be something like what's shown below where lineHeight is a percentage adjustment of font-size.

1 = (calculated font size) 1 0.5 = (calculated font size) 0.5 1.5 = (calculated font size) * 1.5

<Textfit lineHeight='1'>your next</Textfit>
<Textfit lineHeight='1'>big</Textfit>
<Textfit lineHeight='1'>beverage</Textfit>
<Textfit lineHeight='1'>boost</Textfit>
<Textfit lineHeight='1'>is here</Textfit>
tylers-username commented 4 years ago

I tried using the onReady callback to set the lineHeight but this creates a callback loop.

tylers-username commented 4 years ago

If this isn't considered for a feature, for anyone else who lands here, I accomplished it with the following:


const setRefLineHeight = (fontSize, scale, reference) => {
    const textFitElement = reference.current;
    if (typeof textFitElement !== "undefined" && textFitElement !== null) {
        textFitElement.style.lineHeight = `${fontSize * scale}px`
    }
}

// The box reference is from material-ui.
<Box component='span' ref={beverageRef} className="uppercase" style={{fontWeight: 700}}>
    <Textfit mode="single"
        onReady={(fontSize) => setRefLineHeight(fontSize, 1, boost)}
        max={1000}>boost</Textfit>
</Box>
acolbourn commented 2 years ago

Thanks tylerssn! This worked awesome. Here's my full component for anyone else working on this: `import React, { useRef } from 'react'; import { Textfit } from 'react-textfit';

export default function MaxText({ text }) { const ref = useRef(null);

const setRefLineHeight = (fontSize, scale, reference) => { const textFitElement = reference.current; if (typeof textFitElement !== 'undefined' && textFitElement !== null) { textFitElement.props.style.lineHeight = ${fontSize * scale}px; } };

return ( <Textfit ref={ref} mode='single' forceSingleModeWidth={false} onReady={(fontSize) => setRefLineHeight(fontSize, 1, ref)} style={{ height: '100%', maxHeight: '100%', lineHeight: 1, padding: '3px', display: 'flex', justifyContent: 'center', alignItems: 'center', '& div': { maxHeight: '100%', }, }} min={10} max={500}

{text} ); } `