Design Bootstrap dynamic nav tabs component - reactjs

I want to design a dynamic nav tabs component. when the card is clicked relevant tab is shown, with the connection arrow and border-color green.
sample code or a suggestion would be much helpful
.

You can use accordion by bootstrap. Use css flexbox to horizontally align the tabs next to each other and bind a javascript method that changes css color properties (arrow, green color) on clicking.
Here is the link - https://getbootstrap.com/docs/4.0/components/collapse/

Here is how you can do :
.js :
import React, { Component } from "react";
import { render } from "react-dom";
import "./style.css";
const App = () => {
const selectBlock = (e) => {
e.target.classList.toggle('selected');
}
return (
<div className="block" onClick={(e) => {selectBlock(e)}}>
<div>Here is the block</div>
<div className="arrow">
<FakeArrow />
</div>
</div>
);
};
const FakeArrow = () => {
return (
<div>
<span className="arrow-down-border" />
<span className="arrow-down" />
</div>
);
};
render(<App />, document.getElementById("root"));
.css :
.block {
position: relative;
width: 150px;
height: 50px;
text-align: center;
border: 2px solid black;
}
.arrow {
display: none;
}
.block.selected {
border: 2px solid #99d32c;
}
.block.selected .arrow {
display: block;
}
/* You need to fake the arrow border with another arrow behind */
.arrow-down-border {
position: absolute;
bottom: -20px;
left: 55px; /* 150px (main block) / 2 -20px (size of the triangle)*/
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid #99d32c;
}
.arrow-down{
position: absolute;
bottom: -17px;
left: 58px; /* 150px (main block) / 2 -17px (size of the triangle)*/
width: 0;
height: 0;
border-left: 17px solid transparent;
border-right: 17px solid transparent;
border-top: 17px solid #ffffff;
}
Here is the repro on Stackblitz.
Of course this is just an example, you have to set a color for the arrows so my advice would be to do it with constants or props. Same thing for the position and others functionality you can add to the FakeArrow component.
Now, it would be waaaayy easier to manage it with an image if you really need a border (this is the tricky part in your requirement), or a simple arrow without border.
You can take a look at this post, it's the same question actually, i used a slightly different way to do it with css, but the result seems to be the same.

Related

How to add animation on container changing its width realtime

I am making a form that expands when the user enters any character/key and gets back to its original width when there is no character left, for the plus point, I want to add animation to that expandable form so it gives a smooth look.
Here is the code and I want this action as follows
Not in React but I made an example in Vanilla JS hope it helps. I used CSS variables for changing width and making it smooth.
Instead of removing svg icons completely try scaling it down to 0 or changing it opacity to 0
const btns = Array.from(document.querySelectorAll('.btn'))
const input = document.querySelector('input')
btns.shift() // for leaving first button
input.addEventListener('input', (event) => {
btns.forEach((btn) => {
if (event.target.value.trim().length > 0) {
btn.classList.add('scale-0')
btn.parentElement.classList.add('width-50')
} else {
btn.classList.remove('scale-0')
if (btn.parentElement.classList.contains('width-50')) {
btn.parentElement.classList.remove('width-50')
}
}
})
})
#import 'https://cdn.jsdelivr.net/gh/KunalTanwar/normalize/css/normalize.inter.min.css';
body {
display: grid;
place-items: center;
}
.row {
--column-gap: 1rem; /* 8px */
width: 100%;
display: flex;
max-width: 525px;
column-gap: var(--column-gap);
}
.row input {
flex-grow: 1;
border-radius: 100vmax;
padding: 0.75rem 1.25rem;
border: 1px solid #c1c1c1;
}
.container {
--column-gap: 0.5rem; /* 16px */
--btn-size: 3.125rem; /* 50px */
flex-shrink: 0;
display: inherit;
column-gap: var(--column-gap);
width: calc(var(--column-gap) * 3 + var(--btn-size) * 4);
transition: width 250ms ease;
}
.container.width-50 {
width: var(--btn-size);
}
.container .btn {
width: var(--btn-size);
border-radius: 50%;
aspect-ratio: 1/1;
border: 1px solid #c1c1c1;
transition: transform 250ms ease;
}
.container .btn.scale-0 {
transform: scale(0);
}
<div class="row">
<div class="container">
<button class="btn">1</button>
<button class="btn">2</button>
<button class="btn">3</button>
<button class="btn">4</button>
</div>
<input type="text" />
</div>

How to Desktop View, Tablet View ,Mobile view change inside a browser ReactJS

I am new to Reactjs . How to add 3 views inside a browser,by automatically change view.
Reference Page Link
You can wrap all your content with a div and control the width of that div.
// App.js
import { useState } from 'react';
import './App.css';
function App() {
const [state, setState] = useState('desktop');
return (
<div className="App">
<button onClick={() => setState('desktop')}>Desktop</button>
<button onClick={() => setState('tablet')}>Tablet</button>
<button onClick={() => setState('phone')}>Phone</button>
<div className={`container ${state}`}>Your content here</div>
</div>
);
}
export default App;
/*App.css*/
.App {
height: 100%;
background-image: -webkit-linear-gradient(0deg, #766dff 0%, #88f3ff 100%);
}
/* General styling */
button {
padding: 0.5rem;
margin: 1rem;
border-radius: 10px;
cursor: pointer;
border: none;
}
.container {
/* General styling */
background-color: whitesmoke;
padding: 1rem;
border-radius: 5px;
margin-top: 1rem;
transition: all 1s;
/* Center the container */
margin-left: auto;
margin-right: auto;
}
.desktop {
width: 90%;
}
.tablet {
width: 768px;
}
.phone {
width: 480px;
}
/* index.css */
/* To make full width and height */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body,
#root {
height: 100%;
}
The above answer is correct. You can simply give a width to the main container to 100% and place your other container with other elements inside of it, also specify width using #mediaqueries(" https://www.w3schools.com/css/css_rwd_mediaqueries.asp "). This way, you can control the elements inside the main container. I can say for sure that you need to try it by yourself and see how everything works, use devtools(there is toogle device toolbar).

Radio Input As Cards - React + Antd

I wanted to create Radio Input Buttons styled Cards.
I am using react js and ant design.
Tried to create my own native component using good old input type="radio".
Connecting them to antd forms wasen't smooth sailing, then I had another idea.
Using antd react Radio component and just passing a card component. That's the working result!
Usage.tsx
// Other Code
<Radio.Group onChange={onChange} value={value} className="cards-container">
<Radio value={FOCUS_LEVEL.Regular} className="radio-input-card-container">
<InputCard
title="First Card"
checked={value === CONSTANT1}
imgPath="../../assets/icon1.svg"
points={["This is a point explain why this card is the best!", "Wow this is also a great point"]} />
</Radio>
<Radio value={FOCUS_LEVEL.DeepFocus} className="radio-input-card-container">
<InputCard
title="Second Card"
checked={value === CONSTANT2}
imgPath="../../assets/icon2.svg"
points={["This point explains why this card is way better", "The other card as shitty points!"]} />
</Radio>
</Radio.Group>
// Other Code
Usage.scss
.cards-container {
display: flex;
justify-content: space-between;
margin-left: 20px;
}
InputCard.tsx
import React from "react"
import Title from "antd/lib/typography/Title";
import "./InputCard.scss"
export function InputCard({ title, checked, imgPath, points }): JSX.Element {
return (
<div className={checked ? "card checked" : "card"}>
<div className="header-container">
<Title className="card-title">{title}</Title>
<img src={imgPath} alt="regular focus"></img>
</div>
<ul>
{points.map((point) =>
<li key={point.toString()}>{point}</li>
)}
</ul>
</div >
);
}
InputCard.scss
.card {
height: 420px !important;
width: 360px !important;
position: relative !important;
left: -45px; // A work around. Placing the card under the native radio button
-webkit-appearance: none;
appearance: none;
border: 2px solid rgba(2,28,53,0.08);
border-radius: 14px;
box-shadow: 7px 7px 15px rgba(2,28,53,0.08);
cursor: pointer;
outline: none;
.header-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
ul {
padding: 0em 1em 0em 2.5em !important;
}
img {
margin: 0.5em 0em 1em 0em;
}
}
.card-title {
font-size: 20px !important;
margin-top: 16px !important;
}
.checked {
transition: border 0.5s ease;
border: 2px solid rgba(255,0,0,0.6);
}
The antd component creates a radio input circle right before the card childe. Moving the card to the left (left: -45px) so the card will include the radio circle is a workaround. I don't want to change too much in the parent component for me to use this InputCard component, and this is my try to do it within the component.

Modal is displayed below the items

I have come into a strange issue that has stopped me for a few hours. I have created a MERN app in which I have a page that I introduce members of a team. I also have a modal for each member triggered by click on member. The problem is that when I create a new member, the modals related to previous members is displayed behind the latter added members. I will attach pictures to more clearly demonstrate what happens.
enter image description here
enter image description here
Here is how I have defined the modal:
const Modal = ({ closeModal, children }) => {
const closeIcon = () => (
<FontAwesome
name='times'
onClick={closeModal}
className='modal-font-awesome'
/>
)
return (
<div id='overlay'>
<div className='content'>
{closeIcon()}
{children}
</div>
</div>
)
}
Here is my scss code for styling the modal:
#overlay {
position: fixed;
display: block;
overflow: hidden;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.content {
margin: 120px auto;
background-color: white;
border-radius: 0.25rem;
width: 70vw;
padding: 2rem;
position: relative;
border-left: 5px solid rgb(37, 153, 124);
}
Do you have any suggestions about what is happening?
Thank you in advance.

why first two item is not working in react?

I have generated the following four buttons but the first two button (More button) is not working.
Here is the code:
BuildControls.js
import React from 'react';
import BuildControl from './BuildControl/BuildControl';
import classes from './BuildControls.css';
const controls = [
{label:'Salad', type:'salad'},
{label:'Bacon', type:'bacon'},
{label:'Cheese', type:'cheese'},
{label:'Meat', type:'meat'}
]
const buildControls =(props)=>(
<div className={classes.BuildControls}>
<p>Current Price: <strong> {props.price} </strong> BDT</p>
{controls.map(ctrl => (
<BuildControl
label ={ctrl.label}
key={ctrl.label}
addIngredient={()=>props.addIngredients(ctrl.type)}
removeIngredient={()=>props.removeIngredient(ctrl.type)}
disabled ={props.disabled[ctrl.type]}
/>
)
)}
<button
disabled={!props.purchaseAble}
className={classes.OrderButton}
onClick ={props.ordered}> ORDER NOW</button>
</div>
);
export default buildControls;
BuildControl.js
import React from 'react';
import classes from './BuildControl.css';
const builControl =(props)=>(
<div className={classes.BuildControl}>
<div className={classes.Label}> {props.label}</div>
<button className={classes.Less} onClick={props.removeIngredient} disabled ={props.disabled}> Less</button>
<button className={classes.More} onClick={props.addIngredient}> More</button>
</div>
);
export default builControl;
as all the button is being generated by loop problem should be same for all button. last two button is working perfectly but first two is not working. It kills my day. I don't know how to debug as I am new in react js. Any help ?
update:
When I remove {classes.BuildControls} from <div className={classes.BuildControls}> it works fine. and here is the css:
.BuildControls {
width: 100%;
background-color: #CF8F2E;
display: flex;
flex-flow: column;
align-items: center;
box-shadow: 0 2px 1px #ccc;
margin: auto;
padding: 10px 0;
}
.OrderButton {
background-color: #DAD735;
outline: none;
cursor: pointer;
border: 1px solid #966909;
color: #966909;
font-family: inherit;
font-size: 1.2em;
padding: 15px 30px;
box-shadow: 2px 2px 2px #966909;
}
.OrderButton:hover, .OrderButton:active {
background-color: #A0DB41;
border: 1px solid #966909;
color: #966909;
}
.OrderButton:disabled {
background-color: #C7C6C6;
cursor: not-allowed;
border: 1px solid #ccc;
color: #888888;
}
.OrderButton:not(:disabled) {
animation: enable 0.3s linear;
}
#keyframes enable {
0% {
transform: scale(1);
}
60% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
Strange! css causes problem in click event. Whats wrong in my code?
Without seeing the complete code, I would guess that addIngredients should be addIngredient in buildControls :
const buildControls =(props)=>(
<div className={classes.BuildControls}>
<p>Current Price: <strong> {props.price} </strong> BDT</p>
{controls.map(ctrl => (
<BuildControl
label ={ctrl.label}
key={ctrl.label}
addIngredient={()=>props.addIngredients(ctrl.type)}
// typo here -------------------------^
If that's not it, please post the addIngredient and removeIngredient methods, including where they are defined and how they are passed down.

Resources