How to style material UI box component to overlay - reactjs

I'm really new when it comes to styling components and making them look the way I want.
My desired outcome is to have two box components that overlap each other for a nice clean look for displaying user stats and remaining targets for the day.
What I have in mind is:
If anyone can give me some pointers with regards to styling the box component to look like the above image, I would be really greatful.

To start please take a look at MUI Box, which provides a great description to play with the Box component of Material-UI.
Here is an example from the link
<Box
sx={{
width: 300,
height: 300,
backgroundColor: 'primary.dark',
'&:hover': {
backgroundColor: 'primary.main',
opacity: [0.9, 0.8, 0.7],
},
}}
/>
sx is being used for styling the Box component and inside this example we can see that we can change the width, height and background color of the box from the component itself. To something similar to what you had requested I took the liberty of using styled-components to style the Box component as follows:
import * as React from "react";
import Box from "#mui/material/Box";
import styled from "styled-components";
const DataBoxContainer = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
top: 20vh;
position: relative;
`;
const StyledOuterBox = styled(Box)`
border-radius: 20px;
position: absolute;
`;
const StyledInnerBox = styled(Box)`
border-radius: 10px;
position: relative;
bottom: 50px;
`;
const StyledData = styled.p`
color: black;
align-self: flex-start;
position: absolute;
bottom: 30px;
margin-inline-start: 20px;
`;
export default function DataBox() {
return (
<DataBoxContainer>
<StyledOuterBox
sx={{
width: 500,
height: 250,
backgroundColor: "gray"
}}
>
<StyledData>test</StyledData>
</StyledOuterBox>
<StyledInnerBox
sx={{
width: 480,
height: 200,
backgroundColor: "blue"
}}
/>
</DataBoxContainer>
);
}
Feel free to play with this example at CodeSandbox
I'm sure this can be improved but can give you an idea on how to start.
Please feel free to ask me any questions on it, as you requested for pointers but I have provided a code.

Related

Style Commponent, Typescript, flex-box, flexbox not displaying correctly

I have a StackBlitz here https://stackblitz.com/edit/react-ts-jefhjh?file=App.tsx,styled.ts
It's a simple react app with Typescript
I have a style component that uses flex-box to position two columbns next to each other.
I'm passing the widths of the columns into the wrapping container like <FlexContainer width={['60%', '40%']}>
And then using the values in the component like
export const FlexContainer = styled.div<IProps>`
border: 1px solid red;
height: 500px;
display: flex:
// align-content: stretch;
.divOne{
border: 2px solid pink;
height: 500px;
width: ${(p) => p.width[0]};
}
.divTwo{
border: 2px solid green;
height: 500px;
width: ${(p) => p.width[1]};
}
`;
Only one the second column is being displayed.
I know the first column is getting a value because if I use align-content: stretch the first column displays but the layout is wrong.
I'm sure the mistake the way I'm using flex-box
How can I get the layout to work ?
There was a colon instead of a semicolon. Use display: flex; instead of display:flex:. See https://stackblitz.com/edit/react-ts-quu5ce?file=App.tsx,styled.ts
import styled from 'styled-components';
interface IProps {
width?: string[];
}
export const FlexContainer = styled.div<IProps>`
border: 1px solid red;
height: 500px;
display: flex;
.divOne{
border: 2px solid pink;
height: 500px;
width: ${(p) => p.width[0]};
}
.divTwo{
border: 2px solid green;
height: 500px;
width: ${(p) => p.width[1]};
}
`;

How can I give a shadow to the TouchableOpacity in React Native?

I am trying to apply shadow to TouchableOpacity in React native. I used both styled-components and inline style.
I have a View component called PaintCon and PainDummy and a TouchableOpacity component called PaintBtn.
I applied shadow to PaintBtn. But the strange thing is that the shadow works just fine, but PaintBtn shows a faint square box that I don't know. Use elevation to get this square. How do I get rid of this?
Below is my code.
const PaintCon = styled.View`
flex-direction: row;
justify-content: center;
align-items: center;
flex:1;
`;
const PainDummy = styled.View`
width: 20%;
justify-content: center;
align-items: center;
flex:1;
`;
const PaintBtn = styled.TouchableOpacity`
width: 80%;
height: 70px;
background-color: lightcyan;
border-radius: 18px;
margin-bottom: 5px;
`;
return (
<PaintCon
>
<PainDummy
>
<PaintBtn
style={{backgroundColor:'#0097E8',
shadowColor: '#52006A',
shadowOffset: {width: 10, height: 3},
shadowOpacity: 50,
elevation: 10,
}}
activeOpacity={0.7}>
</PaintBtn>
<Text>#0097E8</Text>
</PainDummy>
</PaintCon>
)
It looks like you've given it a different background color (lightCyan in the PaintBtn styled component style). If you remove that background color, it should work?
You don't need to use TouchableOpacity like that. Refer my example given below,
<TouchableOpacity style={styles.card}>
{{------My Codes-----}}
</TouchableOpacity>
And the styles are,(For your reference I had set the ShadowColor to green),
const styles = StyleSheet.create({
card: {
backgroundColor: "#FFFFFF",
padding: 15,
margin: 10,
borderRadius: 15,
shadowColor: "green",
elevation: 15,
flexDirection: "row",
flex: 1,
justifyContent: "space-between"
}

Flexbox Container with Child in it with position absolute

I'm new to React, and I'm currently building a slideshow on my website. Basically, I have a left arrow, the slide content, then the right arrow in my flexbox for my slideshow. However, to make my arrows on the edges of the screen I needed to use position absolute, which messes up my flexbox container. I figured out that absolutely positioned child items don't count in the flexbox of the parent, but is there a way around that? As of now, my image is overlapping with the left arrow. Thanks, and sorry if this is poorly written since I'm very new to this all. Code will be below.
Image: [1]: https://i.stack.imgur.com/PkL3Z.jpg
import { ArrowBackIosOutlined, ArrowForwardIosOutlined } from '#material-ui/icons'
import React from 'react'
import styled from 'styled-components'
import grocery from '../assets/grocery.png'
const Container = styled.div`
width: 100%;
height: 100vh;
display: flex;
position: relative;
`
const Arrow = styled.div`
width: 50px;
height: 50px;
background-color: #fff7f7;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
bottom: 0;
left: ${props => props.direction === "left" && "10px"};
right: ${props => props.direction === "right" && "10px"};
margin: auto;
cursor: pointer;
opacity: 0.5;
`
const Wrapper = styled.div`
height: 100%;
`
const Slide = styled.div`
width; 100vw;
height: 100vh;
display: flex;
align-items: center;
`
const ImageContainer = styled.div`
height: 100%;
flex: 1;
margin-top: 50px;
`
const Image = styled.img`
height: 50%;
`
const InfoContainer = styled.div`
flex: 1;
`
const Slider = () => {
return (
<Container>
<Arrow direction="left">
<ArrowBackIosOutlined/>
</Arrow>
<Wrapper>
<Slide>
<ImageContainer>
<Image src={https://images.unsplash.com/photo-1481349518771-20055b2a7b24?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8cmFuZG9tfGVufDB8fDB8fA%3D%3D&w=1000&q=80}/>
</ImageContainer>
</Slide>
</Wrapper>
<Arrow direction="right">
<ArrowForwardIosOutlined/>
</Arrow>
</Container>
)
}
export default Slider

Typescript/React: Referring to other styled-components

I am trying to reproduce this code from https://styled-components.com/docs/advanced in typescript.
const Link = styled.a`
display: flex;
align-items: center;
padding: 5px 10px;
background: papayawhip;
color: palevioletred;
`;
const Icon = styled.svg`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
${Link}:hover & {
fill: rebeccapurple;
}
`;
What do I have to do for it to work in typescript?
The problem was that I was trying to reference a component that I imported from another file instead of that component's styled counterpart. I mistakenly thought it was a typescript issue.

By using styled components, how can I add some opacity to a background color that comes from an external prop?

This is my code, below it you will find the question
import { printIntrospectionSchema } from 'graphql';
import React, { useContext, useState } from 'react';
import styled from 'styled-components';
import { Context } from '../../../Context/Context';
// DATA
function DurationIntervalSelection() {
const tabsData = [
{
text: 'Duration',
},
{
text: 'Interval',
},
];
// STATE
const [selectedIndex, setselectedIndex] = useState(0);
const { selected } = useContext(Context);
console.log(selected.color, 'selected color');
// FUNCTION
const handleIndexSelection = (index) => {
setselectedIndex(index);
};
return (
<Container>
<TabsContainer backgroundColor={selected.backgroundColor}>
<Indicator
backgroundColor={selected.color}
style={{
left: `${selectedIndex * 50}%`,
}}
/>
{tabsData.map((tab, index) => {
return (
<Tab
style={{
color: selectedIndex === index ? 'white' : 'black',
}}
onClick={() => handleIndexSelection(index)}
key={tab.text}
>
<p style={{ zIndex: 100 }}>{tab.text}</p>
</Tab>
);
})}
</TabsContainer>
</Container>
);
}
const Container = styled.div`
margin-top: 10px;
border: 1px solid #f2f2f7;
border-radius: 10px;
box-sizing: border-box;
padding: 10px 0;
`;
const Indicator = styled.div`
width: 50%;
position: absolute;
/* z-index: -1; */
height: 100%;
border-radius: 20px;
cursor: pointer;
transition: all 0.3s;
background-color: ${(props) => props.backgroundColor};
`;
const TabsContainer = styled.div`
display: flex;
width: 100%;
justify-content: space-between;
position: relative;
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
border-radius: 20px;
overflow: hidden;
background-color: ${(props) => props.backgroundColor};
`;
const Tab = styled.div`
display: flex;
width: 50%;
justify-content: center;
cursor: pointer;
align-items: center;
padding: 10px;
`;
export default DurationIntervalSelection;
As you can see from the above code i pass backgroundColor as a prop that takes some color from a React state.
<TabsContainer backgroundColor={selected.backgroundColor}>
And in the styled component I do:
background-color: ${(props) => props.backgroundColor};
But my question is, since i need to follow a design made by a colleague, how do i add opacity to the above background color without affecting the opacity of the whole div: TabsContainer. I mean, if i add on the TabsContainer -> opacity: 0.3 - for instance the whole TabsContainer div will be affected by the opacity, including the Tab div, while what I want is just to change opacity on the color itself so i do not affect any child. I hope it makes sense. Is there a way?
Okay if your hex value comes from your backend, you can either create your own javascript function that converts hex to rgba or you can use a library like polished. They have a function named rgba that converts a hex string and adds an alpha value to it
import { rgba } from 'polished'
const div = styled.div`
background: ${(props) => rgba(props.backgroundColor, 0.3)};
`
Or you can apply it directly to the prop
<TabsContainer backgroundColor={rgba(selected.backgroundColor, 0.3)}>
Example CodeSandbox.
Since the data from the backend where right but I could not find a solution I have realised that I could have added to
<TabsContainer backgroundColor="rgba(255,255,255, 0.5)">
A background color on the white notes with opacity so to emphasise the color behind it in a lighter way

Resources