“Code over a tile”// React – from sass files to Styled-Components. [PART II]

The data

Each chat window has an array of messages where each one has the name of the sender, the time and the message like


{
  from:'rob'
  time:'13:23pm'
  message:'hi'
}

After that when the message is sent the array is updated and the component Messages is rendered.

The Controls

messages.js

import React from 'react';
import './messages.scss';

const Messages = ({
    messages,
    from
}) =>
    messages.map((data, index) =>
        
'message-row' key={index}> <div className={(from===data.from?' sender':' receiver')}>
{data.time}
{data.from +":"}
{data.message}
div> </div> ) export default Messages

messages.scss

.message-row{
    width:100%;
    float:left;
    .sender-name{
        color:#4e7ea8;
        word-break: initial;
        width:100%;
        margin-right:50px;
        font:18px/20px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;
    }
    .sender-message{
        width:100%;
        margin-left:10px;
        float:left;
        font:12px/18px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;
    }
    .sender-time{
        float: right;
        font: 11px/20px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;
        color: grey;
    }
}

.receiver{
    float:left;
    padding:5px 10px 5px 10px;
    margin-left:30px;
    margin-top:10px;
    position: relative;
    background: #FFFFFF;
    border-radius: .4em;
    max-width: 450px;
    word-break: break-all;
}

.receiver:after {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 0;
    height: 0;
    border: 20px solid transparent;
    border-right-color: #FFFFFF;
    border-left: 0;
    border-bottom: 0;
    margin-top: -10px;
    margin-left: -20px;
}

.sender{
    padding:5px 10px 5px 10px;
    margin-right:30px;
    margin-top:10px;
    float:right;
    position: relative;
    background: #a4e893;
    border-radius: .4em;
    max-width: 450px;
    word-break: break-all;
}

.sender:after {
    content: '';
    position: absolute;
    right: 0;
    top: 50%;
    width: 0;
    height: 0;
    border: 20px solid transparent;
    border-left-color: #a4e893;
    border-right: 0;
    border-bottom: 0;
    margin-top: -10px;
    margin-right: -20px;
}

So as we did it in the Part I, we’re going to create styled components, in this case that we have nested divs a good approach is go from bottom to top changing small components first.

First add the Styled components library.

import styled from 'styled-components'

As we see in the messages.js we have three divs: sender name, sender time, and sender message. So we’re going to create four styled.div components with the styles.

const MessageRow = styled.div`
    width:100%;
    float:left;
}`

const SenderName =  styled.div`
    color:#4e7ea8;
    word-break: initial;
    width:100%;
    margin-right:50px;
    font:18px/20px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;`

const SenderMessage =  styled.div`
    width:100%;
    margin-left:10px;
    float:left;
    font:12px/18px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;
`
const SenderTime =  styled.div`
    float: right;
    font: 11px/20px 'Open Sans',"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,Verdana,sans-serif;
    color: grey;
`

Then we can change our code in order to use them and the message render looks like this

messages.map((data, index) =>
        
            <div className={(from===data.from?' sender':' receiver')}>
                {data.time}
                {data.from +":"}
                {data.message}
            div>
        </MessageRow>
Until now the steps are similar to PART I, now we need to change the div that with some conditional style to make a difference on the message owner. (see screenshot)

To do this we create the styled.div component and change it on our renderer then send to the control the attribute data as a boolean.

NOTE: If you send a boolean like (true,false) you will see an error like “Warning: Received `false` for a non-boolean attribute ..” So you should send a boolean as an integer.

        
            <Message data={from===data.from?1:0}>
                {data.time}
                {data.from +":"}
                {data.message}
            Message>
        </MessageRow>
For this you can use passed props , and write a function to use the props as variables inside functions like
 background :${ props=>props.data? '#a4e893':'#FFFFFF' }

So the idea is that, we check if the value is the owner or not as a boolean and then you can set the correct style for each css property. So you Message Component should look like.

const Message = styled.div`
    position: relative;
    padding:5px 10px 5px 10px;
    margin-top:10px;
    word-break: break-all;
    max-width: 450px;
    border-radius: .4em;
    background :${ props=>props.data? '#a4e893':'#FFFFFF' }
    float: ${props=> props.data? 'right':'left'};
    margin-left:${props=>props.data?'':'30px'};
    margin-right:${props=>props.data?'30px':''};
    &::after{
        content: '';
        position: absolute;
        top: 50%;
        width: 0;
        height: 0;
        border: 20px solid transparent;
        border-bottom: 0;
        margin-top: -10px;

        //sender
        right: ${props=>props.data? '0':''};
        left: ${props=>props.data? '':'0'};

        border-right-color: ${props=>!props.data? '#FFFFFF':''};
        border-left-color: ${props=>props.data ? '#a4e893':''};
        border-right: ${props=>props.data?'0':''};
        border-left: ${props=>!props.data?'0':''};

        margin-right:${props=>props.data?'-20px':''};
        margin-left:${props=>!props.data?'-20px':''};
    }

IMHO I’ll try to keep simple the functions in the styles in order to understand easy what is doing.

I hope this help you to change your code and make it more comprehensive and simple . Feedback is a simple way to share knowledge and is always welcome 🙂

read original article here