Is it possible to use Array.map within a template literal to dynamically generate CSS rules for multiple media queries?

In this scenario, I am attempting to iterate through props to generate css rules for multiple media queries.

How to Use

<FlexContainerExperimental
    direction="column"
    mediaQueries={[
        {mediaQueryMinWidth: props.theme.minWidthLargeDevice, direction: 'row'},
        {mediaQueryMinWidth: props.theme.minWidthMediumDevice, direction: 'row', itemsPerLane: 2},
    ]}
>
    ...
</FlexContainerExperimental>

Custom Styled Component

interface FlexContainerSettings {
    direction?: string;
    itemsPerLane?: number;
}

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

interface MediaQuery extends FlexContainerSettings {
    mediaQueryMinWidth: string;
}

// tslint:disable:no-any
const Container = styled.div<FlexContainerExperimentalProps>`
    display: flex;
    margin-left: -${props => props.theme.itemHorizontalMargin};
    margin-top: -${props => props.theme.itemVerticalMargin};

    flex-direction: ${props => props.direction};

    ${props => props.mediaQueries && props.mediaQueries.map((mediaQuery: MediaQuery) => `
        @media all and (min-width: ${mediaQuery.mediaQueryMinWidth}) {
            flex-direction: ${mediaQuery.direction};
            ${mediaQuery.itemsPerLane && `
                flex-wrap: wrap;
                & > * {
                    flex: 1 1 calc(${100 / mediaQuery.itemsPerLane}% - ${
                        mediaQuery.direction === 'column' || 
                        (!mediaQuery.direction && props.direction === 'column') 
                        ? props.theme.itemVerticalMargin 
                        : props.theme.itemHorizontalMargin}
                    );
                }
            `};
        };
    `).join()};
`;

function FlexContainerExperimental(props: FlexContainerExperimentalProps) {
    const { children, ...rest } = props;

    return (
        <Container {...rest}>
            {children}
        </Container>
    );
}

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

Issue Encountered

It seems that only the first media query in the array is being applied. To put it differently, the behavior changes based on the order of objects within the mediaQueries array.

mediaQueries={[
        {mediaQueryMinWidth: props.theme.minWidthMediumDevice, direction: 'row', itemsPerLane: 2},
        {mediaQueryMinWidth: props.theme.minWidthLargeDevice, direction: 'row'},
    ]}

Answer №1

I found the solution by inserting an additional line after each media query.

const Box = styled.div<FlexExperimentalProps>`
    display: flex;
    margin-left: -${props => props.theme.itemHorizontalMargin};
    margin-top: -${props => props.theme.itemVerticalMargin};

    flex-direction: ${props => props.direction};

    ${props => props.mediaQueries && props.mediaQueries.map((query: MediaQuery) => `
        @media all and (min-width: ${query.mediaQueryMinWidth}) {
            flex-direction: ${query.direction};
            ${query.itemsPerLane && `
                flex-wrap: wrap;
                & > * {
                    flex: 1 1 calc(${100 / query.itemsPerLane}% - ${
                        query.direction === 'column' || 
                        (!query.direction && props.direction === 'column') 
                        ? props.theme.itemVerticalMargin 
                        : props.theme.itemHorizontalMargin}
                    );
                }
            `};
        }

    `).join('\n')};
`;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring Angular 4's capability: Incorporating data from Http Post Response into a .js file or highchart

I'm a beginner with Angular 4. I'm trying to create a dashboard that pulls data from an Http Post Response and I want to use this data to create a Chart (Highchart). I have successfully received the response in the console.log and formatted it i ...

What is the method for adjusting the spacing between binding tags within HTML code formatting specifically for TypeScript elements in IntelliJ?

My Angular binding currently defaults to <h1>{{typeScriptVar}}</h1>, but I would like it to be set as <h1>{{ typeScriptVar }}</h1> when I use the format code shortcut in InteliJ. Can anyone assist me with this issue? I have resear ...

Asynchronous function in TypeScript is restricting the return type to only one promise type

Using node version 14.7.0, npm version 6.14.7, and typescript version 3.7.3. I have a function that interacts with a postgres database and retrieves either the first row it finds or all results based on a parameter. It looks something like this: async fet ...

Fill up the table using JSON information and dynamic columns

Below is a snippet of JSON data: { "languageKeys": [{ "id": 1, "project": null, "key": "GENERIC.WELCOME", "languageStrings": [{ "id": 1, "content": "Welcome", "language": { ...

What causes the appearance of the "?" symbol at the beginning of the URL and triggers a reboot of the app when moving through the absolute path?

I am facing an issue. In my multi-module application with lazy loading, I encountered a strange behavior when trying to navigate between child lazy modules. Transition from top module to bottom child module works fine, but routing from one bottom child la ...

Integrating d3.js into an Angular 2 project

Trying to incorporate the d3.js library into a MEAN application using angular2. Here are the steps I've taken: npm install d3 tsd install d3 In mypage.ts file (where I intend to show the d3.js graph) // <reference path="../../../typings/d3/d3.d ...

Combining Multiple .ts Files into a Single File: A Simplified Application Structure with TypeScript 1.8

Currently, I am in the process of developing an Electron application and I have decided to implement TypeScript for this project. While TypeScript essentially boils down to JavaScript in the end, my familiarity with it makes the transition seamless. As of ...

The data type of the element is implicitly set to 'any' due to the fact that a 'string' expression cannot be used to reference the type '(controlName: string) => boolean'

checkError(typeofValidator: string, controlName: string): boolean { return this.CustomerModel.formCustomerGroup.contains[controlName].hasError(typeofValidator); } I am currently learning Angular. I came across the same code in a course video, but it i ...

Utilizing D3 to fetch geographic data in the form of a TopoJSON file for U.S. counties

After retrieving a set of coordinates, the goal is to use D3 to find the corresponding county from a U.S. TopoJSON file. Here is an example code snippet: navigator.geolocation.getCurrentPosition(function(position) { let coordinates: [number, number] = [p ...

Encountering an issue with core.js:15723 showing ERROR TypeError: Unable to access property 'toLowerCase' of an undefined value while using Angular 7

Below, I have provided my code which utilizes the lazyLoading Module. Please review my code and identify any errors. Currently facing TypeError: Cannot read property 'toLowerCase' of undefined in Angular 7. Model Class: export class C_data { ...

Angular/TypeScript restricts object literals to declaring properties that are known and defined

I received an error message: Type '{ quantity: number; }' is not assignable to type 'Partial<EditOrderConfirmModalComponent>'. Object literal may only specify known properties, and 'quantity' does not exist in type &ap ...

What is the process for assigning a predefined type that has already been declared in the @types/node package?

Is there a way to replace the any type with NetworkInterfaceInfo[] type in this code snippet? Unfortunately, I am unable to import @types/node because of an issue mentioned here: How to fix "@types/node/index.d.ts is not a module"? Here is the o ...

Navigating to a specific attribute within a higher-level Component

Within my top-level Component, I have a property that is populated with data from an HTTP source. Here is how it is implemented in a file named app.ts: import {UserData} from './services/user-data/UserData'; Component({ selector: 'app& ...

Vue caution: The reference to property or method "list" during render is not defined on the instance. Ensure that this property is reactive and properly declared

I'm currently exploring the characters from the Rick & Morty series app using vue.js, and I am still learning how to use vue.js. However, I encountered the following error and would appreciate help in resolving it: Error1: [Vue warn]: Property or me ...

The response parser in Angular 7 is failing to function correctly

Hey, I recently updated my Angular from version 4.4 to the latest 7 and after encountering several errors, I was able to get my service up and running. However, I'm facing an issue with my output parser function which is supposed to parse the login re ...

Why am I encountering the 'nonexistent type' error in my Vue 3 project that uses Typescript and Vuelidate?

Seeking assistance with a Vue 3 and Vuelidate issue. I followed the configuration guide provided at . <script lang="ts"> import { required, minLength, maxLength, numeric } from '@vuelidate/validators' import useVuelidate from &apo ...

Instantiate a TypeScript object and establish its type by setting restrictions derived from an input object

I have been working on creating a function that takes an object A: { [key: string]: string | undefined } as its parameter. The goal is to generate a new object B with all properties from A, converting each string property to type number, and each string | ...

Extracting PDF files using API within Angular services

I have set up a Java-based API on a server, with the URL being "ex.com". This API has an endpoint that returns a PDF file, with the URL set as "ex.com/pdf". For this endpoint, a POST request is required with a parameter specifying the requested PDF, like ...

While using axios to make a GET request, I encountered errors when checking for .isSuccess in react

const searchInvoiceList = async ( plantLocation: string, invoiceType: string ) => { let dataList: InvoiceData[] = []; await axios .get(`${linkURL}inv/getControlList/${plantLocation}/${invoiceType}`) .then((response) => { dataLis ...

The issue of circular dependencies in TypeScript arises specifically within the Record type rather than in an ordinary object type

Can you explain the difference between two types, where one throws a TS error and the other does not? type ScopeItem = | string | { all: string; team: string; }; type ScopesTree = Record<string, ScopeItem | Record& ...