Code Monkey home page Code Monkey logo

Comments (19)

pablosichert avatar pablosichert commented on July 17, 2024 12

If you don't need to be able to resize the container, you can add a css rule like that:

.your-truncate-class > span {
    white-space: nowrap;
}

Of course the line breaks will still be calculated wrong, but at least the lines will have the same width and are aligned (and hopefully not break out of your design).

Thank you for reporting anyway, I am sure other people might bump into that as well.

Closing this issue since this is out of the scope of the component, unfortunatly.

I might come back to this issue when I have a demo playground running for this repository.

from react-truncate.

jariz avatar jariz commented on July 17, 2024 5

I wrote a (sorta) elegant solution to this that forces truncate to rerender itself upon font face load completion.
You'll need recompose (or write a hoc that renders a component itself) & fontfaceonload

import { lifecycle } from 'recompose';
import onFontFaceLoad from 'fontfaceonload';

// little HOC that force updates it's contents once a font face is loaded

export default (fontFace) =>
    lifecycle({
        componentDidMount () {
            onFontFaceLoad(fontFace, {
                success: () => {
                    setTimeout(() => this.forceUpdate(), 0);
                }
            });
        },
    });

Then, from the component that consumes the library:

import withFontLoadRender from ...

const UpdatingTruncate = withFontLoadRender('YourFontFamily')(Truncate);

export default () => (
    <UpdatingTruncate lines={2}>Text to truncate</UpdatingTruncate>
)

(I have no idea why the setTimeout is needed, but it is)

from react-truncate.

bjcancin avatar bjcancin commented on July 17, 2024 2

Hi. I solve this creating a ReadMore (as in the examples) using the document.fonts.ready html event. I use the ready state to catch when the fonts are already loaded and to set expanded=false.

import { useState, useEffect } from 'react';
import Truncate from 'react-truncate';

export default function ReadMore({ lines, children }) {

    const [expanded, setExpanded] = useState(true);
    const [truncated, setTruncated] = useState(false);
    const [ready, setReady] = useState(false);

    function handleTruncate(t) {
        if (truncated !== t) setTruncated(t);
    }

    function toggleLines(e) {
        e.preventDefault();
        setExpanded(!expanded);
    }

    useEffect(() => {
        
        if (ready) return;

        document.fonts.ready.then(function () {
            setReady(true);
            setExpanded(false);
        });
    });

    return (
        <>
            <Truncate
                lines={!expanded && lines}
                ellipsis={<span>...  <button className="readMore" onClick={toggleLines}>Ver Más</button></span>} onTruncate={handleTruncate}>
                {children}
            </Truncate>
            {!truncated && expanded && (
                <span>...  <button className="readMore" onClick={toggleLines}>Ver Menos</button></span>
            )}
        </>
    )
}

from react-truncate.

pablosichert avatar pablosichert commented on July 17, 2024 1

If this was the cause, it would be a pretty hard problem to solve within this module.

I could do some arbitrary canvas checks before and after rendering and see if they give the same width. However, this would also not guarantee that it works 100% of the time, just reduce the probability of failure.

My advise here is to put your stylesheet into the page head and block page rendering until it's done loading and make sure that your font file is served as fast as possible (CDN, cached).

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024 1

Thanks Pablo for your help, very much!

from react-truncate.

unyo avatar unyo commented on July 17, 2024 1

Suggested fix: Use font-family: 'Custom Font', 'Courier New', sans-serif in order to prevent the weird line breaking when the custom font is loaded and increases in width, as Truncate works before the font loads. Courier New will need to be wider than the custom font.

from react-truncate.

pablosichert avatar pablosichert commented on July 17, 2024

I'm missing a bit of a context here to figure out where the problem might be.

Could you provide some additional information about:

  • What's the exact value of titleToTruncate? (If it's a component, what kind of render output does it produce, or if a plain string, the full string)
  • Print window.getComputedStyle(document.querySelector('h2.title')) and paste it here
  • A screenshot of that scenario

Assuming you are using the latest version of react-truncate and either of an up-to-date version Chrome, Firefox or Edge?

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

Hi Pablo, thanks for your quick reply, some context:
title is a string passed through prop to the component that has the react-truncate, the string is

"El tope en la devolución por cláusulas suelo aleja las fusiones bancarias. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis dui nulla, hendrerit et nunc sed, hendrerit elementum ipsum";

the getComputedStyle gives:
window.getComputedStyle(document.querySelector('.blabla__title')); CSSStyleDeclaration {0: "animation-delay", 1: "animation-direction", 2: "animation-duration", 3: "animation-fill-mode", 4: "animation-iteration-count", 5: "animation-name", 6: "animation-play-state", 7: "animation-timing-function", 8: "background-attachment", 9: "background-blend-mode", 10: "background-clip", 11: "background-color", 12: "background-image", 13: "background-origin", 14: "background-position", 15: "background-repeat", 16: "background-size", 17: "border-bottom-color", 18: "border-bottom-left-radius", 19: "border-bottom-right-radius", 20: "border-bottom-style", 21: "border-bottom-width", 22: "border-collapse", 23: "border-image-outset", 24: "border-image-repeat", 25: "border-image-slice", 26: "border-image-source", 27: "border-image-width", 28: "border-left-color", 29: "border-left-style", 30: "border-left-width", 31: "border-right-color", 32: "border-right-style", 33: "border-right-width", 34: "border-top-color", 35: "border-top-left-radius", 36: "border-top-right-radius", 37: "border-top-style", 38: "border-top-width", 39: "bottom", 40: "box-shadow", 41: "box-sizing", 42: "break-after", 43: "break-before", 44: "break-inside", 45: "caption-side", 46: "clear", 47: "clip", 48: "color", 49: "content", 50: "cursor", 51: "direction", 52: "display", 53: "empty-cells", 54: "float", 55: "font-family", 56: "font-kerning", 57: "font-size", 58: "font-stretch", 59: "font-style", 60: "font-variant", 61: "font-variant-ligatures", 62: "font-variant-caps", 63: "font-variant-numeric", 64: "font-weight", 65: "height", 66: "image-rendering", 67: "isolation", 68: "left", 69: "letter-spacing", 70: "line-height", 71: "list-style-image", 72: "list-style-position", 73: "list-style-type", 74: "margin-bottom", 75: "margin-left", 76: "margin-right", 77: "margin-top", 78: "max-height", 79: "max-width", 80: "min-height", 81: "min-width", 82: "mix-blend-mode", 83: "motion-offset", 84: "motion-path", 85: "motion-rotation", 86: "object-fit", 87: "object-position", 88: "opacity", 89: "orphans", 90: "outline-color", 91: "outline-offset", 92: "outline-style", 93: "outline-width", 94: "overflow-wrap", 95: "overflow-x", 96: "overflow-y", 97: "padding-bottom", 98: "padding-left", 99: "padding-right"…}

Just to give more context, this is a big application, with lots of reducers, etc (so it has some busy miliseconds). The react-truncate component is the latests one and im using latest chrome browser, but it also happens in chromium and firefox.

It also uses webpack and inline styles, not sure if that can affect

Thank you for your help and work

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

screenshot from 2016-09-29 14-24-09

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

the style is

.blabla{
padding: 12px;
overflow: auto;

&__title {
    margin-bottom: 12px;
    font-size: 18px;
    line-height: 28px;
}

}

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

screenshot

another screenshot as is randomic, weird

from react-truncate.

pablosichert avatar pablosichert commented on July 17, 2024

Thank you for the context :-)

This seems to be either related to the font size or the overflow: auto;.

When the component mounts it renders the full children, then figures out how much space it can use and then renders the truncated version. If you don't have a scroll bar when you mount the component but have a scroll bar once the component is done rendering, there would be some ~17px (width of the scroll bar) missing.

Could you make a try with replacing all your overflows to overflow: scroll or overflow: hidden, so that the available width does not jump back and forth?

Just to be sure - this is not on mobile, right? (There is a known issue)

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

nope, desktop

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

i replaced the overflow with hidden and is the same, just to give you another clue, when i open the inspector (and resizes) renders correctly, so i guess is related with the first mount/calculation

from react-truncate.

pablosichert avatar pablosichert commented on July 17, 2024

That's some valuable information.

Could you open $<your-editor> ./node_modules/react-truncate/lib/Truncate.js and paste in

target && console.log(target.parentNode.getBoundingClientRect().width);

between those lines? (The code looks slightly different after having gone through babel - just find a line in the render method where target is already defined).

To not clutter the console it would be helpful if you could only mount the affected <Truncate> component.

Then let's see what numbers you get, they should not vary between renders.

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

number doesnt change, logs 304 all the time, before and after resizing but is still rendered incorrect at the beggining and correct after resize

from react-truncate.

pablosichert avatar pablosichert commented on July 17, 2024

Okay.

Then I'm pretty sure it's about the font.

Could it be that a custom font is not loaded yet at the first render?

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

ill be back to you, diagnosing now, seems you are right...

from react-truncate.

santiagoRebella avatar santiagoRebella commented on July 17, 2024

if I put style={{fontFamily: 'Verdana'}}in the title tag or in the title class i get as screenshot below, still not correct for a lines={4} , but it doesnt changes on resize.

newformat

If i dont and leave as I have (weird webpack setup with inline plugin and so on) i get first:

formatbad

and after resize (as I think it should be)

goodafterresize

So obviously font and probably webpack, and how is being handled fonts and styles by webpack can be the issue, but is weird why only in the third case is the output as expected, and not in the first case.

from react-truncate.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.