I have a mapped array that I want to pass a variable into SCSS so that it can change a variable width

I have a function that maps an array of values from another file. The specific constant I want to work with is item?.level, which is of the format 1 | 2 | 3 | 4 | 5. What I see happening is in my *.scss file that I somehow do width: calc(100% * {item?.level} / 5);. This means that at level 1 the width is at 20%, and at level 5 the width is at 100%.

Here is my code of just the *.tsx:

    
{
    (children ?? []).map((item) => {
        return (
            <div className="point">
                <div className="point-title">{item?.title}</div>
                <div className="point-level">{item?.level}/5</div>
                <div className={item?.level + " out of 5"}>
                    <div className="point-level">
                        <div className="stars-outer">
                            <div className="stars-inner"></div>
                        </div>
                    </div>
                </div>
                {item?.description && (
                    <div className="point-description">{item?.description}</div>
                )}
            </div>
        );
    });
}

I just want to make it clear, that the constant {item?.level} is predetermined from another Typescript file, it is always of the form 1 | 2 | 3 | 4 | 5, but is nested in an unspecified length array, so map() is needed to display each item.

1 thought on “I have a mapped array that I want to pass a variable into SCSS so that it can change a variable width”

  1. The pure CSS way to do this would be using attr(). However, no browser seems to currently support it being used in this way.

    Since you are using React and SCSS, you have multiple alternatives:

    • Use inline styles, for example <div style={{ width: `calc(100% * ${item?.level} / 5)` }}>
    • Use a helper library such as styled-components, define a custom component: const Item = styled.div`width: calc(100% * ${(props) => props.level} / 5)`; and then use it as <Item level={item?.level}>
    • Put the level in the class name: <div className={`point-level-${item?.level}`}>. Since you support only 5 levels, manually define styles for .point-level-1, … Or use a custom attribute like <div data-level={item?.level}> and specify styles for [data-level=1], …
      • SCSS makes it possible to define all classes at once using a for loop. I have never used this before, but it should look something like this: @for $i from 1 through 5 { .point-level-#{$i} { width: calc(100% * #{$i} / 5 }
    Reply

Leave a Comment