How to customize react-popper arrow - css

How to set arrow style the same as the popper
import React from "react";
import ReactDOM from "react-dom";
import { Manager, Reference, Popper } from "react-popper";
function App() {
return (
<Manager>
<Reference>
{({ ref }) => (
<button type="button" ref={ref}>
Reference element
</button>
)}
</Reference>
<Popper placement="right">
{({ ref, style, placement, arrowProps }) => (
<div
ref={ref}
style={style}
className={`popover show bs-popover-${"right"}`}
>
<div className="popover-inner bg-primary">Popper element</div>
<div
className="arrow bg-primary"
ref={arrowProps.ref}
style={arrowProps.style}
/>
</div>
)}
</Popper>
</Manager>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
Code Sandbox: https://codesandbox.io/s/bold-shape-lomrm

First, add this CSS:
.bs-popover-auto[x-placement^=right] .arrow::after, .bs-popover-right .arrow::after {
border-right-color: #007bff;
}
Get rid of bg-primary class from the .arrow and give this style:
style="top: -2px;"
Preview
Demo: https://codesandbox.io/s/eager-wu-h337q

Related

props is undefined when passing from parent to component in next js

I have /pages/profile.js which calls the LovedOne element, passing values from props.
Debugging shows that these values are valid when passed
import React from "react";
import LovedOne from "../components/loved_one";
export const Profile = ({ loved_ones }) => {
const [session, loading] = useSession();
if (loading) return <div>loading...</div>;
if (!session) return <div>no session</div>;
return (
<Layout>
{session && (
<>
<img src={session.user.image} className="avatar" />
<h1>{session.user.name}</h1>
</>
)}
{loved_ones.map((loved_one, index) => (
<LovedOne
key={index}
firstname={loved_one.firstname}
surname={loved_one.surname}
email={loved_one.email}
/>
))}
<style jsx>{`
.avatar {
width: 220px;
border-radius: 10px;
}
`}</style>
</Layout>
);
};
However in /components/loved_one.js my props is undefined
import React, { useState, useRef } from "react";
export const LovedOne = ({ props }) => {
const [setActive, setActiveState] = useState("");
const [setHeight, setHeightState] = useState("0px");
const content = useRef();
function toggleAccordion() {
setActiveState(setActive === "" ? "active" : "");
setHeightState(
setActive === "active" ? "0px" : `${content.current.scrollHeight}px`
);
}
return (
<div>
<div className="row">
<button
className={`collection-item ${setActive}`}
onClick={toggleAccordion}
>
<i className="fas fa-plus teal-text"></i>
</button>
<div className="col s2">
{props.firstname} {props.surname}
</div>
<div className="col s2">{props.email}</div>
</div>
<div ref={content} style={{ maxHeight: `${setHeight}` }}>
<span>some stuff</span>
</div>
</div>
);
};
export default LovedOne;
I've tried passing single variables, and passing the entire loved_ones object. I get the same problem.
Any help much appreciated!
Have you tried passing props instead of {props} ?
lose brackets, try this way:
export const LovedOne = (props) => {

Flex spacing for horizontal components in React JS

I have a footer which has three elements, I want to distribute them horizontally. I tried to space them horizontally using flex and space-between. Here is my react Component:
import React from "react";
export default function Footer()
{
const Element1 = "GZB Automation";
const today = new Date();
const DayFormat = today.toString().split(" ").slice(0,4);
const Element3 = DayFormat.filter(Boolean).join(" ");
console.log(Element3);
const Element2 = "Copyright © "+today.getFullYear().toString()+". All rights reserved.";
return(
<div className="FooterAligner">
<div className="FooterElement">{Element1}</div>
<div className="FooterElement">{Element2}</div>
<div className="FooterElement">{Element3}</div>
</div>
);
}
CSS of the FooterAligner and FooterElement is as shown:
.FooterAligner
{
display: flex;
justify-content: space-between;
bottom: 2%;
position:fixed;
}
.FooterElement
{
width: calc(100%/3);
}
Here is how they appear:
And this is how I want them to appear:
P.S. Ignore the font-styling, text part, and slight background variations, I just want to know about spacing.
HomePage Script (app.js):
import React from 'react';
import StarterScreen from './components/screens/StarterScreen.jsx';
import LoginScreen from './components/screens/LoginScreen.jsx';
import RegisterScreen from './components/screens/RegisterScreen.jsx';
import DisplayScreen from './components/screens/DisplayScreen.jsx';
import 'bootstrap/dist/css/bootstrap.min.css';
import Footer from './components/junk/Footer.jsx';
//import LineChart from './components/coreComponents/LineChart.js';
import ProtectedRoute from './components/security/PrivateRoute.jsx';
import './App.css';
import {BrowserRouter,Route,Switch} from 'react-router-dom';
function App(){
return (
<div className="App">
<BrowserRouter>
<Switch>
<Route component={StarterScreen} exact path="/"></Route>
<Route component={RegisterScreen} exact path="/register"></Route>
<Route component={LoginScreen} exact path="/login"></Route>
<ProtectedRoute component={DisplayScreen} exact path="/login-props-test" />
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
export default App;
For reproduction: https://codesandbox.io/s/i8r3u
Since you're using Bootstrap in your project, why not leverage the flexbox utility classes it comes with?
In this particular example I added the d-flex class to the footer container. This converts it to a flex container, so then you can add justify-content-between, which would distribute the available space between elements:
function Footer() {
const element1 = "GZB Automation";
const today = new Date();
const dayFormat = today.toString().split(" ").slice(0, 4);
const element3 = dayFormat.filter(Boolean).join(" ");
const element2 = `Copyright © ${today
.getFullYear()
.toString()}. All rights reserved.`;
return (
<footer className="d-flex justify-content-between">
<div className="p-2">{element1}</div>
<div className="p-2">{element2}</div>
<div className="p-2"> {element3} </div>
</footer>
);
}
class App extends React.Component {
render() {
return (
<div>
Rest of the app goes here..
<Footer />
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Note: The class p-2 is a Bootstrap utility class that adds padding to each child inside the flex container

Material UI and React &hover selector not working

I have this code in which the hover selector doesn't work at all. Everything else when it comes to style works perfectly but the hover doesn't do anything visible.
import React from "react";
import Paper from '#material-ui/core/Paper';
import Grid from '#material-ui/core/Grid';
const styles = {
divStyle: {
width: "300px",
height: "200px",
backgroundColor: "red",
margin: "30px",
'&:hover': {
border: '5px solid #000000',
bordeBottomColor: 'transparent',
borderRightColor: 'transparent'
}
}
};
const StartPage = ()=> {
return(
<React.Fragment>
<Paper>
<div style={styles.firstContainer}>
</div>
<div style={styles.secondContainer}>
<Grid container >
<Grid style={styles.Grid} item>
<div style={styles.gridDivStyle}>
<div style={styles.divStyle}></div>
<div style={styles.divStyle}></div>
</div>
<div style={styles.gridDivStyle}>
<div style={styles.divStyle}></div>
<div style={styles.divStyle}></div>
</div>
</Grid>
</Grid>
</div>
<div style={styles.lastContainer}>
</div>
</Paper>
</React.Fragment>
);
}
export default StartPage;
How can I make the hover selector work. Do I need to use the state from React in order to make the change?
if you want to use hover style , you can use the package
import { withStyles } from 'material-ui/styles';
Here is the code:
import React from "react";
import Paper from "#material-ui/core/Paper";
import Grid from "#material-ui/core/Grid";
import { withStyles } from "#material-ui/styles";
const styles = {
divStyle: {
width: "300px",
height: "200px",
backgroundColor: "red",
margin: "30px",
"&:hover": {
border: "5px solid #000000",
bordeBottomColor: "transparent",
borderRightColor: "transparent"
}
}
};
const StartPage = props => {
return (
<React.Fragment>
<Paper>
<div style={styles.firstContainer} />
<div style={styles.secondContainer}>
<Grid container>
<Grid style={styles.Grid} item>
<div style={styles.gridDivStyle}>
<div className={props.classes.divStyle} /> // use the styles through className
<div className={props.classes.divStyle} />
</div>
<div style={styles.gridDivStyle}>
<div className={props.classes.divStyle} />
<div className={props.classes.divStyle} />
</div>
</Grid>
</Grid>
</div>
<div style={styles.lastContainer} />
</Paper>
</React.Fragment>
);
};
export default withStyles(styles)(StartPage);
Working Demo

React tutorial - css not loading

I'm working through a tutorial on React/Spring Boot located here. All was going well, including the initial display of groups on React.
However, once the React piece was refactored to separate the group list into a separate module and a nav bar was added, I get a display without any css rendering.
Here is the code:
App.js
import React, { Component } from 'react';
import './App.css';
import Home from './Home';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import GroupList from './GroupList';
class App extends Component {
render() {
return (
<Router>
<Switch>
<Route path='/' exact={true} component={Home}/>
<Route path='/groups' exact={true} component={GroupList}/>
</Switch>
</Router>
)
}
}
export default App;
AppNavbar.js
import React, { Component } from 'react';
import { Collapse, Nav, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
import { Link } from 'react-router-dom';
export default class AppNavbar extends Component {
constructor(props) {
super(props);
this.state = {isOpen: false};
this.toggle = this.toggle.bind(this);
}
toggle() {
this.setState({
isOpen: !this.state.isOpen
});
}
render() {
return <Navbar color="dark" dark expand="md">
<NavbarBrand tag={Link} to="/">Home</NavbarBrand>
<NavbarToggler onClick={this.toggle}/>
<Collapse isOpen={this.state.isOpen} navbar>
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink
href="https://twitter.com/oktadev">#oktadev</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://github.com/oktadeveloper/okta-spring-boot-react-crud-example">GitHub</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>;
}
}
Home.js
import './App.css';
import AppNavbar from './AppNavbar';
import { Link } from 'react-router-dom';
import { Button, Container } from 'reactstrap';
class Home extends Component {
render() {
return (
<div>
<AppNavbar/>
<Container fluid>
<Button color="link"><Link to="/groups">Manage JUG Tour</Link></Button>
</Container>
</div>
);
}
}
export default Home;
GroupList.js
import React, { Component } from 'react';
import { Button, ButtonGroup, Container, Table } from 'reactstrap';
import AppNavbar from './AppNavbar';
import { Link } from 'react-router-dom';
class GroupList extends Component {
constructor(props) {
super(props);
this.state = {groups: [], isLoading: true};
this.remove = this.remove.bind(this);
}
componentDidMount() {
this.setState({isLoading: true});
fetch('api/groups')
.then(response => response.json())
.then(data => this.setState({groups: data, isLoading: false}));
}
async remove(id) {
await fetch(`/api/group/${id}`, {
method: 'DELETE',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(() => {
let updatedGroups = [...this.state.groups].filter(i => i.id !== id);
this.setState({groups: updatedGroups});
});
}
render() {
const {groups, isLoading} = this.state;
if (isLoading) {
return <p>Loading...</p>;
}
const groupList = groups.map(group => {
const address = `${group.address || ''} ${group.city || ''} ${group.stateOrProvince || ''}`;
return <tr key={group.id}>
<td style={{whiteSpace: 'nowrap'}}>{group.name}</td>
<td>{address}</td>
<td>{group.events.map(event => {
return <div key={event.id}>{new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: 'long',
day: '2-digit'
}).format(new Date(event.date))}: {event.title}</div>
})}</td>
<td>
<ButtonGroup>
<Button size="sm" color="primary" tag={Link} to={"/groups/" + group.id}>Edit</Button>
<Button size="sm" color="danger" onClick={() => this.remove(group.id)}>Delete</Button>
</ButtonGroup>
</td>
</tr>
});
return (
<div>
<AppNavbar/>
<Container fluid>
<div className="float-right">
<Button color="success" tag={Link} to="/groups/new">Add Group</Button>
</div>
<h3>My JUG Tour</h3>
<Table className="mt-4">
<thead>
<tr>
<th width="20%">Name</th>
<th width="20%">Location</th>
<th>Events</th>
<th width="10%">Actions</th>
</tr>
</thead>
<tbody>
{groupList}
</tbody>
</Table>
</Container>
</div>
);
}
}
export default GroupList;
App.css
.App {
text-align: center;
}
.container, .container-fluid {
margin-top: 20px;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
#media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
#keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
Any help much appreciated.
If I understand correctly, you are not using the classes you define in the App.css file.
To use the styles add the className property to the element where you need the styling.
For example, in your home.js:
<Button className="App-link" color="link"><Link to="/groups">Manage JUG Tour</Link></Button>
As in the example App.js you linked:
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<div className="App-intro">
<h2>JUG List</h2>
{groups.map(group =>
<div key={group.id}>
{group.name}
</div>
)}
</div>
</header>
</div>
);
It was my fault, I just needed to add this into index.js, which was right in the instructions:
import 'bootstrap/dist/css/bootstrap.min.css';

CSS Positioning elements in a header

So I'm trying to create a navigational menu header and it also includes a logo in it, fairly simple but some of the buttons the left side are inline-block with the logo itself and they appear at the bottom of the logo, to the right of it based on ordering, but at the bottom and im not sure how with css to get them to go to the top of the container or if the roof of their container is just lower that I'm thinking?
import React from 'react';
import {Link} from 'react-router-dom';
import { AuthService } from './backend/client/auth';
import { Paper, Button } from '#material-ui/core';
import { withStyles } from '#material-ui/core/styles';
const styles = theme => ({
container: {
'height': 128,
},
leftnav: {
'display': 'inline-block',
},
rightnav: {
'float': 'right',
},
button: {
'display': 'inline-block',
}
});
class Header extends React.Component {
render() {
const { classes } = this.props;
return (
<Paper className={classes.container}>
<div className={classes.leftnav}>
<Link to="/" className={classes.button}>
<img src="https://imageserver.eveonline.com/Corporation/98523546_128.png" alt="Hole Puncher's Logo"></img>
</Link>
<Button component={Link} to="/">
Home
</Button>
<Button component={Link} to="/store">
Browse
</Button>
<Button component={Link} to="/contact-us">
Contact Us
</Button>
</div>
<div className={classes.rightnav}>
{AuthService.isAuthed()
? <Button component={Link} to="/account/orders">Account</Button>
: ''}
{AuthService.isAuthed()
? <Button component={Link} to="/login">Login</Button>
: <Button onClick={AuthService.logout} component={Link} to="/login"></Button>}
</div>
</Paper>
)
}
}
export default withStyles(styles)(Header);
https://i.imgur.com/OnTjO4l.png
Multiple ways to solve it using CSS. Simplest way is to use vertical-align: top in your button class. I would however recommend you look into display: flex. It's much easier for vertical alignment.
Working JSFiddle here: http://jsfiddle.net/Lhefbudx/
Hope this helps.

Resources