user1283776
user1283776

Reputation: 21764

Possible to loop over props in styled component tag?

I am trying to create a FlexContainer that can accept any number of media queries with some props attached to each media query.

This is how I want to use it:

<FlexContainerExperimental mediaQueries={[{minWidth: props.theme.minWidthMediumDevice, direction: 'column'}]}>
    {textPosts}
</FlexContainerExperimental>

This is how I implement the FlexContainerExperimental

interface FlexContainerSettings {
    alignItems?: string;
    direction?: string;
    width?: string;
    justifyContent?: string;
}

interface FlexContainerExperimentalProps extends FlexContainerSettings {
    // tslint:disable-next-line:no-any
    children: any;
    className?: string;
    mediaQueries?: MediaQuery[];
}

interface MediaQuery extends FlexContainerSettings {
    minWidth: string;
}

function FlexContainerExperimental(props: FlexContainerExperimentalProps) {
    const Container = styled.div`
        display: flex;

        ${props.alignItems && `justify-content: ${props.alignItems}`};
        ${props.direction && `justify-content: ${props.direction}`};
        ${props.width && `justify-content: ${props.width}`};
        ${props.justifyContent && `justify-content: ${props.justifyContent}`};

        ${props && props.mediaQueries && 
                props.mediaQueries.map((mediaQuery: MediaQuery) => `
                    @media all and (min-width: ${mediaQuery.minWidth}) {
                        direction: ${mediaQuery.direction};
                        alignItems: ${mediaQuery.alignItems};
                        width: ${mediaQuery.width};
                        justify-content: ${mediaQuery.justifyContent};
                    };
            `)};

    `;
    return (
        <Container className={props.className}>
            {props.children}
        </Container>
    );
}

export { FlexContainer, FlexContainerExperimental };
export * from './FlexItem';

I don't get any error, but the media query has no effect and seems to not be rendered to css at all.

What am I doing wrong?

Upvotes: 0

Views: 1051

Answers (1)

Ricardinho
Ricardinho

Reputation: 1339

You're returning an Array. Make sure to return a Template literal:

${({ mediaQueries }) => {
    let templateLiteral = ``;
    mediaQueries.forEach(mediaQuery => {
        templateLiteral += `
            @media all and (min-width: ${mediaQuery.minWidth}) {
                direction: ${mediaQuery.direction};
                alignItems: ${mediaQuery.alignItems};
                width: ${mediaQuery.width};
                justify-content: ${mediaQuery.justifyContent};
            };
        `;
    });
    return templateLiteral;
}}

https://stackoverflow.com/a/53220251/2248347

Upvotes: 1

Related Questions