Tips for adjusting the horizontal position of a grid item within a map() loop

I am trying to align the text in my Timeline component from Material Ui always towards the center of the timeline. The TimelineContent contains Paper, Typography (for title and description), and an image.

Currently, I have multiple TimelineContent elements created using .map() function, so simply using flex-direction: row-reverse won't solve the issue.

Here is a visual example of the problem:

  • The first TimelineContent has the text aligned to the left, which is correct.
  • The second TimelineContent has the text not aligned properly to the right.

Below is the code snippet I am currently working with:

<Timeline align="alternate">
           {result.map((index) => {
                return (
                        <TimelineItem className={classes.timelineStyle}>

                            <TimelineOppositeContent>
                                <Typography variant="body2" color="textSecondary">
                                    {index.sif_date}
                                </Typography>
                            </TimelineOppositeContent>

                                <TimelineSeparator>
                                    <TimelineDot className={classes.dot}>
                                        <LaptopMacIcon/>
                                    </TimelineDot>
                                <TimelineConnector />
                                </TimelineSeparator>

                            <TimelineContent>
                                <Paper elevation={3} className={classes.paper}>
                                    
                                    <Grid style={{display: 'flex', flexWrap: 'nowrap'}}>
                                        <Grid item>
                                            <Typography variant="h6" component="h1">
                                                {index.sif_titre}
                                            </Typography>
                                            <Typography style={{fontSize: 'smaller'}}>
                                                {index.sif_msg}
                                            </Typography>
                                        </Grid>

                                        <Grid item>
                                            <Zoom overlayBgColorStart='rgba(73, 80, 87, 67)' overlayBgColorEnd='rgba(73, 80, 87, 67)' zoomMargin={100}>
                                                <img src={index.sif_image} alt={index.sif_image} className={classes.img} style={{maxWidth: 200, maxHeight: 200}}/>
                                            </Zoom>
                                        </Grid>
                                    </Grid>

                                </Paper>
                            </TimelineContent>

                        </TimelineItem>
                )
                })
            }
        </Timeline>
const useStyles = makeStyles((theme) => ({
  paper: {
    padding: '6px 16px',
    textAlign: 'center',
    backgroundColor: 'white !important',
    display: 'flex'
    ...
}));

Edit:

Here is the full code snippet for my page:

import React from 'react';
...
export default index;

Answer №1

To achieve this effect, utilize the nth-child selector in CSS to alternate between styles and flex directions.

For more information on the nth-child selector, check out: https://developer.mozilla.org/de/docs/Web/CSS/:nth-child

.parent{
  display: flex;
  flex-directrion: row;
}

.parent:nth-child(2n+1){ /* or: :nth-child(odd) */
  flex-direction: row-reverse;
}
<div class="parent">
  <div class="img">IMG</div>
  <div class="txt">txt</div>
</div>
<div class="parent">
  <div class="img">IMG</div>
  <div class="txt">txt</div>
</div>
<div class="parent">
  <div class="img">IMG</div>
  <div class="txt">txt</div>
</div>
<div class="parent">
  <div class="img">IMG</div>
  <div class="txt">txt</div>
</div>

Answer №2

To determine if we're on an even or odd iteration, I recommend using a modulo operation. Additionally, I have defined the title component as a variable to avoid redundancy:

{result.map((index, i) => {
    
    let isEven = i % 2 === 0,
        titleComponent = (
            <Grid item>
                <Typography variant="h6" component="h1">
                    {index.sif_titre}
                </Typography>
                <Typography style={{fontSize: 'smaller'}}>
                    {index.sif_msg}
                </Typography>
            </Grid>
        );
    
    return (
        <TimelineItem className={classes.timelineStyle}>

            <TimelineOppositeContent>
                <Typography variant="body2" color="textSecondary">
                    {index.sif_date}
                </Typography>
            </TimelineOppositeContent>

            <TimelineSeparator>
                <TimelineDot className={classes.dot}>
                    <LaptopMacIcon/>
                </TimelineDot>
                <TimelineConnector />
            </TimelineSeparator>

            <TimelineContent>
                <Paper elevation={3} className={classes.paper}>

                    <Grid style={{display: 'flex', flexWrap: 'nowrap'}}>

                        {isEven && titleComponent}

                        <Grid item>
                            <Zoom overlayBgColorStart='rgba(73, 80, 87, 67)' overlayBgColorEnd='rgba(73, 80, 87, 67)' zoomMargin={100}>
                                <img src={index.sif_image} alt={index.sif_image} className={classes.img} style={{maxWidth: 200, maxHeight: 200}}/>
                            </Zoom>
                        </Grid>

                        {!isEven && titleComponent}

                    </Grid>

                </Paper>
            </TimelineContent>

        </TimelineItem>
    )
})}

For a demonstration of how the modulo operator works, you can check out this example: https://jsfiddle.net/q12yah85/

Answer №3

Let's create a custom styled timeline item in React using Material-UI:
 
const CustomTimelineItem = withStyles({
  alignAlternate: {
    "&:nth-child(even) .MuiTimelineItem-content": {
      direction: "rtl"
    }
  }
})(TimelineItem);

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

Setting a Javascript value to a Controller variable within an ASP.NET MVC View

I am trying to set the javascript variable contentArea to match content.Contents in my controller. How can this be accomplished? <script language="javascript" type="text/javascript"> $("#btnTest").click(function () { var content ...

Trouble encountered with card flip style login form in Vue.js, as the card is not maintaining its position properly during transition animations

Need help styling a login/signup component in Vue.js where flipping between the two cards isn't working smoothly. The transition is causing one card to move down and right while the other comes in from the bottom right. It's hard to explain the i ...

Reposition the element at the bottom of its parent element

I am facing an issue with the HTML structure in my application: <div class="work-item"> <div class="image-container"> </div> <div class="text-container"> </div> </div ...

When my route in NextJS processes the request, it returns a ReadableStream from req

I am encountering an issue with my code and I have tried looking for solutions in other similar questions without any success. Is there anyone who can assist me? Here is the content of my route.js file: import dbConnect from "@/lib/dbConnect"; i ...

Instruct the component to reset its state when closing

My current dilemma involves dealing with a parent owning a ModalComponent: render(){ return ( <MyCustomModal visible={this.state.displayModal} //other properties /> ); } The MyCustomModal component carries its own state, referred to as ...

Dealing with errors: React does not allow objects to be rendered as children

My current code includes the following: import React, {Component, useMemo } from "react"; class TimeslotPicker extends Component { constructor(props) { super(props); this.state = { error: '', ...

Unable to set a specific position for adding a new option in a dropdown menu

I have implemented a semantic UI dropdown using the code below: $('.ui.dropdown') .dropdown() ; <html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <l ...

Beautiful ExpressionChangedAfterItHasBeenCheckedError

I need your help Input field where I can enter a Student email or IAM, which will be added to a string array List displaying all the students I have added, using a for loop as shown below Delete button to remove a student from the array The list has a sp ...

What is the method for producing an li and anchor tag using a list object?

Here is the response I received from my web service, and now I need to transform it into a list item tag: {"d":[{"name":"ttt","url":"bbbb"},{"name":"uuu","url":"ppp"}]} How can I create li tags based on the above output? This is the desired format for t ...

React throwing error: Context value is undefined

Why is the Context value showing as undefined? The issue lies in src/Context.js: import React, { Component } from 'react'; const Context = React.createContext(); export class Provider extends Component { state = { a: 1, b: 2 }; render( ...

Reduce the size of a container element without using jquery

In my Angular application, I have structured the header as follows: -- Header -- -- Sub header -- -- Search Box -- -- Create and Search Button -- -- Scroll Div -- HTML: <h1> Header </h1> <h3> Sub header </h3> <div class="s ...

The ng-repeat function is not functioning properly when used within an li element to trigger

I have utilized the Dialog service to create a pop-up window. My intention is to display a message to the user in this format: txt = '<ul> <li data-ng-repeat = "eachValue in dummnyList" > {{eachValue | applyFilte ...

What is the correct method for implementing useEffect in React to ensure it only runs once and satisfies eslint react-hooks/exhaustive-deps?

Having an issue with eslint's react-hooks/exhaustive-deps. My component needs to only be called once regardless of prop changes. It works fine when using an empty array, but multiple calls occur when specifying dependencies. Here is a snippet of my c ...

I'm experiencing a lack of feedback while implementing jQuery/AJAX with JSONP

Attempting to perform a cross-domain request using jQuery/AJAX, I have the code below; $.ajax({ url: "http://www.cjihrig.com/development/jsonp/jsonp.php?callback=jsonpCallback&message=Hello", crossDomain:true }) .done(function( msg ) { alert( ...

The filter settings of MUI DataGrid (Pro) will not be displayed if the filterModel is applied using the filterModel property

When using a Mui Data Grid, I encountered an issue where the filter settings were not saving between reloads. To address this, I stored the filter settings in a context that synced with the browser's session storage. The filter itself runs server-side ...

Difficulty Establishing a Connection with SQL Server Using TypeORM

My local machine is running an SQL Server instance, but I'm encountering an error when trying to connect a database from TypeORM. The error message reads: originalError: ConnectionError: Failed to connect to localhost:1433 - Could not connect (seque ...

There are two separate CSS files linked to the same page, but the browser is only rendering the styles from

I am in the process of developing a new web page where I want to implement my own CSS and incorporate some components from this source: . I'm facing an issue with one of the components, as the browser seems to be applying only the styles from my custo ...

Incorporate a local asciinema file into an HTML document

Is there a way to embed a local asciinema session into an html file? Here is how my directory is structured: $ tree . ├── asciinema │ └── demo.cast ├── css │ └── asciinema-player.css ├── index.html ├── js │ ...

Placing content retrieved from a MySQL database within a form displayed in a ColorBox

Having difficulty inserting text from a MySQL database into a form (textfield) inside a ColorBox. The current script is as follows: <a href="#" class="bttn sgreen quote1">Quote</a> var postQuote[<?php echo 4id; ?>]=<?php echo $f ...

The functionality of a Google chart is determined by the value of the AngularJS $scope

I recently started working with AngularJS and Google charts. I've successfully created a Google chart using data from AngularJS. It's functioning properly, but now I want to make the chart dynamic based on my Angular Scope value. I have a filter ...